[Scummvm-git-logs] scummvm master -> 60c7f3351610e5794e0cb8dcf8187ced3bf51b39
dreammaster
dreammaster at scummvm.org
Wed Jul 28 05:04:09 UTC 2021
This automated email contains information about 21 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
10dfe6cdcc AGS: Janitorial for lib/std/ folder
7a1ee192e2 AGS: Fixup character's view loop in update, prevent having no frame
69157077cf AGS: Fixed Path::GetParent (now it actually works)
5e37a5515b AGS: Implemented GetFiles and GetDirs through the same algorithm
00ade063b9 AGS: In File api functions replaced quit with a warning on error
5ccb07acf9 AGS: implemented bool Room.Exists(int room)
47928c39aa AGS: changed Object.SetView default loop & frame values to 0
5b4ce2d365 AGS: support source rectangle for DrawImage
37c51eeac5 AGS: Support extended params for DrawSurface
9f78c2f22c AGS: Added WaitMouse() to complement existing Wait funcs
b4997729cd AGS: Wait functions return the actual reason they were skipped
0b4b055d6f AGS: Wait functions may have infinite timeout with <0 time arg
529362a2d7 AGS: implemented SkipWait()
9612b5cb35 AGS: distinct overlay types of speech and messagebox
c133e51620 AGS: Speech.TextOverlay for accessing blocking speech overlay
217e55e2d9 AGS: Speech.PortraitOverlay for accessing speech portrait overlay
65f992979e AGS: Implemented Game.BlockingWaitSkipped
e93845cb0c AGS: added eSkipNone to SkipSpeechStyle
cf36b34f0d AGS: Implemented Object.ManualScaling and Object.Scaling
28102f13ab AGS: allow Character.Scaling full range (1-32767)
60c7f33516 AGS: Update engine sync point comments
Commit: 10dfe6cdcc5c6a84343c1a960ac3492878cbac5c
https://github.com/scummvm/scummvm/commit/10dfe6cdcc5c6a84343c1a960ac3492878cbac5c
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:34-07:00
Commit Message:
AGS: Janitorial for lib/std/ folder
Changed paths:
engines/ags/lib/std/algorithm.h
engines/ags/lib/std/array.h
engines/ags/lib/std/chrono.h
engines/ags/lib/std/functional.h
engines/ags/lib/std/limits.h
engines/ags/lib/std/list.h
engines/ags/lib/std/map.h
engines/ags/lib/std/math.h
engines/ags/lib/std/memory.h
engines/ags/lib/std/queue.h
engines/ags/lib/std/set.h
engines/ags/lib/std/type_traits.h
engines/ags/lib/std/unordered_set.h
engines/ags/lib/std/utility.h
engines/ags/lib/std/vector.h
engines/ags/lib/std/xtr1common.h
engines/ags/lib/std/xutility.h
diff --git a/engines/ags/lib/std/algorithm.h b/engines/ags/lib/std/algorithm.h
index e657619b04..d7ff0e4690 100644
--- a/engines/ags/lib/std/algorithm.h
+++ b/engines/ags/lib/std/algorithm.h
@@ -30,100 +30,100 @@ namespace AGS3 {
namespace std {
template<typename T> inline T abs(T x) {
-return ABS(x);
+ return ABS(x);
}
template<typename T> inline T min(T a, T b) {
-return MIN(a, b);
+ return MIN(a, b);
}
template<typename T> inline T max(T a, T b) {
-return MAX(a, b);
+ return MAX(a, b);
}
template<typename T> inline T clip(T v, T amin, T amax) {
-return CLIP(v, amin, amax);
+ return CLIP(v, amin, amax);
}
template<typename T> inline T sqrt(T x) {
-return ::sqrt(x);
+ return ::sqrt(x);
}
template<typename T> inline void swap(T &a, T &b) {
-SWAP(a, b);
+ SWAP(a, b);
}
template<class In, class Value>
In fill(In first, In last, const Value &val) {
-return Common::fill(first, last, val);
+ return Common::fill(first, last, val);
}
template<typename T, class StrictWeakOrdering>
void sort(T first, T last, StrictWeakOrdering comp) {
-Common::sort(first, last, comp);
+ Common::sort(first, last, comp);
}
template<typename T>
void sort(T *first, T *last) {
-Common::sort(first, last, Common::Less<T>());
+ Common::sort(first, last, Common::Less<T>());
}
template<class T>
void sort(T first, T last) {
-Common::sort(first, last);
+ Common::sort(first, last);
}
template<class In, class T>
In find(In first, In last, const T &v) {
-return Common::find(first, last, v);
+ return Common::find(first, last, v);
}
template<class T>
T unique(T first, T last) {
-T pos;
-for (pos = first + 1; pos < last; ++pos) {
- // Check for duplicate
- for (T existingPos = first; existingPos < last; ++existingPos) {
- if (*pos == *existingPos) {
- // Found a match, so shift values over the duplicate
- while (pos < (last - 1)) {
- T &prior = pos;
- ++pos;
- prior = pos;
+ T pos;
+ for (pos = first + 1; pos < last; ++pos) {
+ // Check for duplicate
+ for (T existingPos = first; existingPos < last; ++existingPos) {
+ if (*pos == *existingPos) {
+ // Found a match, so shift values over the duplicate
+ while (pos < (last - 1)) {
+ T &prior = pos;
+ ++pos;
+ prior = pos;
+ }
+
+ --last;
+ break;
}
-
- --last;
- break;
}
}
-}
-return pos;
+ return pos;
}
template<class ForwardIt, class T>
ForwardIt lower_bound(ForwardIt first, ForwardIt last, const T &value) {
-for (ForwardIt it = first; it < last; ++it) {
- if (*it >= value)
- return it;
-}
+ for (ForwardIt it = first; it < last; ++it) {
+ if (*it >= value)
+ return it;
+ }
-return last;
+ return last;
}
template<class ForwardIt, class T>
ForwardIt upper_bound(ForwardIt first, ForwardIt last, const T &value) {
-for (ForwardIt it = first; it < last; ++it) {
- if (*it > value)
- return it;
-}
+ for (ForwardIt it = first; it < last; ++it) {
+ if (*it > value)
+ return it;
+ }
-return last;
+ return last;
}
template<class ForwardIt, class T, class Compare>
ForwardIt upper_bound(ForwardIt first, ForwardIt last, const T &value, Compare comp) {
-for (ForwardIt it = first; it < last; ++it) {
- if (comp(value, *it))
- return it;
-}
+ for (ForwardIt it = first; it < last; ++it) {
+ if (comp(value, *it))
+ return it;
+ }
-return last;
+ return last;
}
} // namespace std
diff --git a/engines/ags/lib/std/array.h b/engines/ags/lib/std/array.h
index d38ad928b5..4505a669f6 100644
--- a/engines/ags/lib/std/array.h
+++ b/engines/ags/lib/std/array.h
@@ -31,11 +31,11 @@ namespace std {
template<class T>
class array : public Common::Array<T> {
public:
-array() : Common::Array<T>() {
-}
-array(size_t size) : Common::Array<T>() {
- Common::Array<T>::resize(size);
-}
+ array() : Common::Array<T>() {
+ }
+ array(size_t size) : Common::Array<T>() {
+ Common::Array<T>::resize(size);
+ }
};
} // namespace std
diff --git a/engines/ags/lib/std/chrono.h b/engines/ags/lib/std/chrono.h
index 3ea5202ce7..50fdf3f6da 100644
--- a/engines/ags/lib/std/chrono.h
+++ b/engines/ags/lib/std/chrono.h
@@ -32,41 +32,41 @@ namespace chrono {
class duration {
private:
-uint32 _value;
+ uint32 _value;
public:
-duration() : _value(0) {
-}
-duration(uint32 value) : _value(value) {
-}
-
-size_t count() const {
- // durations for ScummVM are hardcoded to be in milliseconds
- return 1000;
-}
-
-operator uint32() const {
- return _value;
-}
-
-inline bool operator>=(const duration &rhs) const {
- return _value >= rhs._value;
-}
+ duration() : _value(0) {
+ }
+ duration(uint32 value) : _value(value) {
+ }
+
+ size_t count() const {
+ // durations for ScummVM are hardcoded to be in milliseconds
+ return 1000;
+ }
+
+ operator uint32() const {
+ return _value;
+ }
+
+ inline bool operator>=(const duration &rhs) const {
+ return _value >= rhs._value;
+ }
};
class milliseconds : public duration {
public:
-milliseconds() : duration(0) {}
-milliseconds(uint32 val) : duration(val) {}
+ milliseconds() : duration(0) {}
+ milliseconds(uint32 val) : duration(val) {}
-static milliseconds zero() {
- return milliseconds();
-}
+ static milliseconds zero() {
+ return milliseconds();
+ }
};
class microseconds : public duration {
public:
-microseconds() : duration(0) {}
-microseconds(long val) : duration(val / 1000) {}
+ microseconds() : duration(0) {}
+ microseconds(long val) : duration(val / 1000) {}
};
@@ -75,15 +75,15 @@ struct system_clock {
struct steady_clock { // wraps QueryPerformanceCounter
-using rep = uint32;
-using period = milliseconds;
-using duration = milliseconds;
-using time_point = uint32;
-static constexpr bool is_steady = true;
-
-static time_point now() { // get current time
- return g_system->getMillis();
-}
+ using rep = uint32;
+ using period = milliseconds;
+ using duration = milliseconds;
+ using time_point = uint32;
+ static constexpr bool is_steady = true;
+
+ static time_point now() { // get current time
+ return g_system->getMillis();
+ }
};
using high_resolution_clock = steady_clock;
@@ -93,7 +93,7 @@ duration duration_cast(T param);
template<class T>
duration duration_cast(T param) {
-return duration(param);
+ return duration(param);
}
} // namespace chrono
diff --git a/engines/ags/lib/std/functional.h b/engines/ags/lib/std/functional.h
index d4625a7321..0827900113 100644
--- a/engines/ags/lib/std/functional.h
+++ b/engines/ags/lib/std/functional.h
@@ -28,27 +28,27 @@ namespace std {
template <class _Arg, class _Result>
struct unary_function { // base class for unary functions
-using argument_type = _Arg;
-using result_type = _Result;
+ using argument_type = _Arg;
+ using result_type = _Result;
};
template <class _Arg1, class _Arg2, class _Result>
struct binary_function { // base class for binary functions
-using first_argument_type = _Arg1;
-using second_argument_type = _Arg2;
-using result_type = _Result;
+ using first_argument_type = _Arg1;
+ using second_argument_type = _Arg2;
+ using result_type = _Result;
};
template <typename _Fty>
struct function {
-_Fty *_fn;
+ _Fty *_fn;
-function() : _fn(nullptr) {}
-function(_Fty *fn) : _fn(fn) {}
+ function() : _fn(nullptr) {}
+ function(_Fty *fn) : _fn(fn) {}
-operator _Fty &() {
- return *_fn;
-}
+ operator _Fty &() {
+ return *_fn;
+ }
};
} // namespace std
diff --git a/engines/ags/lib/std/limits.h b/engines/ags/lib/std/limits.h
index 8767068d4f..97448d50f7 100644
--- a/engines/ags/lib/std/limits.h
+++ b/engines/ags/lib/std/limits.h
@@ -35,37 +35,36 @@ class _Num_base {
template <class _Ty>
class numeric_limits : public _Num_base {
public:
-static constexpr _Ty(min)() {
- return _Ty();
-}
-
-static constexpr _Ty(max)() {
- return _Ty();
-}
+ static constexpr _Ty(min)() {
+ return _Ty();
+ }
+ static constexpr _Ty(max)() {
+ return _Ty();
+ }
};
template <>
class numeric_limits<float> {
public:
-static constexpr float quiet_undefined() {
- return FLOAT_UNASSIGNED;
-}
+ static constexpr float quiet_undefined() {
+ return FLOAT_UNASSIGNED;
+ }
};
template <>
class numeric_limits<uint16_t> {
public:
-static constexpr uint16_t quiet_undefined() {
- return 0;
-}
+ static constexpr uint16_t quiet_undefined() {
+ return 0;
+ }
-static constexpr uint16_t min() {
- return 0;
-}
-static constexpr uint16_t max() {
- return UINT16_MAX;
-}
+ static constexpr uint16_t min() {
+ return 0;
+ }
+ static constexpr uint16_t max() {
+ return UINT16_MAX;
+ }
};
} // namespace std
diff --git a/engines/ags/lib/std/list.h b/engines/ags/lib/std/list.h
index 22f99e9a25..f153118275 100644
--- a/engines/ags/lib/std/list.h
+++ b/engines/ags/lib/std/list.h
@@ -57,18 +57,18 @@ public:
}
};
public:
-typename Common::List<T>::iterator insert(typename Common::List<T>::iterator pos,
- const T &element) {
- Common::List<T>::insert(pos, element);
- return pos;
-}
+ typename Common::List<T>::iterator insert(typename Common::List<T>::iterator pos,
+ const T &element) {
+ Common::List<T>::insert(pos, element);
+ return pos;
+ }
-reverse_iterator rbegin() {
- return reverse_iterator(Common::List<T>::reverse_begin());
-}
-reverse_iterator rend() {
- return reverse_iterator(Common::List<T>::end());
-}
+ reverse_iterator rbegin() {
+ return reverse_iterator(Common::List<T>::reverse_begin());
+ }
+ reverse_iterator rend() {
+ return reverse_iterator(Common::List<T>::end());
+ }
};
} // namespace std
diff --git a/engines/ags/lib/std/map.h b/engines/ags/lib/std/map.h
index 7333badd1c..15bbbe012c 100644
--- a/engines/ags/lib/std/map.h
+++ b/engines/ags/lib/std/map.h
@@ -31,184 +31,184 @@ namespace std {
template<class Key, class Val, class CompFunc = Common::Less<Key> >
class map {
-struct KeyValue {
- Key _key;
- Val _value;
-};
+ struct KeyValue {
+ Key _key;
+ Val _value;
+ };
private:
-Common::Array<KeyValue> _items;
-CompFunc _comp;
-public:
-using iterator = typename Common::Array<KeyValue>::iterator;
-using const_iterator = typename Common::Array<KeyValue>::const_iterator;
+ Common::Array<KeyValue> _items;
+ CompFunc _comp;
+ public:
+ using iterator = typename Common::Array<KeyValue>::iterator;
+ using const_iterator = typename Common::Array<KeyValue>::const_iterator;
+
+ /**
+ * Clears the map
+ */
+ void clear() {
+ _items.clear();
+ }
-/**
- * Clears the map
- */
-void clear() {
- _items.clear();
-}
+ /**
+ * Gets the iterator start
+ */
+ iterator begin() {
+ return _items.begin();
+ }
-/**
- * Gets the iterator start
- */
-iterator begin() {
- return _items.begin();
-}
+ /**
+ * Get the iterator end
+ */
+ iterator end() {
+ return _items.end();
+ }
-/**
- * Get the iterator end
- */
-iterator end() {
- return _items.end();
-}
+ /**
+ * Get the const iterator start
+ */
+ const_iterator begin() const {
+ return _items.begin();
+ }
-/**
- * Get the const iterator start
- */
-const_iterator begin() const {
- return _items.begin();
-}
+ /**
+ * Get the const iterator end
+ */
+ const_iterator end() const {
+ return _items.end();
+ }
-/**
- * Get the const iterator end
- */
-const_iterator end() const {
- return _items.end();
-}
+ /**
+ * Returns an iterator for the first element of the map that is
+ * not less than the given key
+ */
+ const_iterator lower_bound(const Key &theKey) const {
+ const_iterator first = this->begin();
+ const_iterator it;
+ int count_ = _items.size(), step;
+
+ while (count_ > 0) {
+ it = first;
+ step = count_ / 2;
+ it += step;
+
+ if (_comp(it->_key, theKey)) {
+ first = ++it;
+ count_ -= step + 1;
+ } else {
+ count_ = step;
+ }
+ }
-/**
- * Returns an iterator for the first element of the map that is
- * not less than the given key
- */
-const_iterator lower_bound(const Key &theKey) const {
- const_iterator first = this->begin();
- const_iterator it;
- int count_ = _items.size(), step;
-
- while (count_ > 0) {
- it = first;
- step = count_ / 2;
- it += step;
-
- if (_comp(it->_key, theKey)) {
- first = ++it;
- count_ -= step + 1;
- } else {
- count_ = step;
+ return first;
+ }
+
+ iterator lower_bound(const Key &theKey) {
+ iterator first = this->begin();
+ iterator it;
+ int count_ = _items.size(), step;
+
+ while (count_ > 0) {
+ it = first;
+ step = count_ / 2;
+ it += step;
+
+ if (_comp(it->_key, theKey)) {
+ first = ++it;
+ count_ -= step + 1;
+ } else {
+ count_ = step;
+ }
}
+
+ return first;
}
- return first;
-}
+ /**
+ * Find the entry with the given key
+ */
+ iterator find(const Key &theKey) {
+ iterator it = this->lower_bound(theKey);
-iterator lower_bound(const Key &theKey) {
- iterator first = this->begin();
- iterator it;
- int count_ = _items.size(), step;
+ if (it != this->end() && it->_key == theKey)
+ return it;
+ return this->end();
+ }
+
+ const_iterator find(const Key &theKey) const {
+ const_iterator it = this->lower_bound(theKey);
- while (count_ > 0) {
- it = first;
- step = count_ / 2;
- it += step;
+ if (it != this->end() && it->_key == theKey)
+ return it;
+ return this->end();
+ }
- if (_comp(it->_key, theKey)) {
- first = ++it;
- count_ -= step + 1;
+ /**
+ * Square brackets operator accesses items by key, creating if necessary
+ */
+ Val &operator[](const Key &theKey) {
+ iterator it = this->lower_bound(theKey);
+ if (it == this->end() || it->_key != theKey) {
+ size_t idx = it - this->begin();
+ _items.insert_at(idx, KeyValue());
+ _items[idx]._key = theKey;
+ return _items[idx]._value;
} else {
- count_ = step;
+ return _items[it - this->begin()]._value;
}
}
- return first;
-}
-
-/**
- * Find the entry with the given key
- */
-iterator find(const Key &theKey) {
- iterator it = this->lower_bound(theKey);
-
- if (it != this->end() && it->_key == theKey)
- return it;
- return this->end();
-}
+ /**
+ * Erases an entry in the map
+ */
+ iterator erase(iterator it) {
+ iterator next = it;
+ ++next;
+ _items.remove_at(it - begin());
+ return next;
+ }
-const_iterator find(const Key &theKey) const {
- const_iterator it = this->lower_bound(theKey);
+ iterator erase(const Key &theKey) {
+ return erase(find(theKey));
+ }
- if (it != this->end() && it->_key == theKey)
- return it;
- return this->end();
-}
+ /**
+ * Returns the size of the map
+ */
+ size_t size() const {
+ return _items.size();
+ }
-/**
- * Square brackets operator accesses items by key, creating if necessary
- */
-Val &operator[](const Key &theKey) {
- iterator it = this->lower_bound(theKey);
- if (it == this->end() || it->_key != theKey) {
- size_t idx = it - this->begin();
- _items.insert_at(idx, KeyValue());
- _items[idx]._key = theKey;
- return _items[idx]._value;
- } else {
- return _items[it - this->begin()]._value;
- }
-}
-
-/**
- * Erases an entry in the map
- */
-iterator erase(iterator it) {
- iterator next = it;
- ++next;
- _items.remove_at(it - begin());
- return next;
-}
-
-iterator erase(const Key &theKey) {
- return erase(find(theKey));
-}
-
-/**
- * Returns the size of the map
- */
-size_t size() const {
- return _items.size();
-}
+ /**
+ * Returns the number of elements with a matching key
+ */
+ size_t count(const Key &theKey) {
+ int count_ = 0;
+ for (iterator it = this->begin(); it != this->end(); ++it) {
+ if (it->_key == theKey)
+ ++count_;
+ }
-/**
- * Returns the number of elements with a matching key
- */
-size_t count(const Key &theKey) {
- int count_ = 0;
- for (iterator it = this->begin(); it != this->end(); ++it) {
- if (it->_key == theKey)
- ++count_;
+ return count_;
}
-
- return count_;
-}
};
template<class Key, class Val, class HashFunc = Common::Hash<Key>,
class EqualFunc = Common::EqualTo<Key> >
class unordered_map : public Common::HashMap<Key, Val, HashFunc, EqualFunc> {
public:
-pair<Key, Val> insert(pair<Key, Val> elem) {
- // unordered_map doesn't replace already existing keys
- if (this->contains(elem.first))
- return pair<Key, Val>(elem.first, this->operator[](elem.first));
-
- // Add item to map
- this->operator[](elem.first) = elem.second;
- return elem;
-}
-
-void reserve(size_t size) {
- // No implementation
-}
+ pair<Key, Val> insert(pair<Key, Val> elem) {
+ // unordered_map doesn't replace already existing keys
+ if (this->contains(elem.first))
+ return pair<Key, Val>(elem.first, this->operator[](elem.first));
+
+ // Add item to map
+ this->operator[](elem.first) = elem.second;
+ return elem;
+ }
+
+ void reserve(size_t size) {
+ // No implementation
+ }
};
} // namespace std
diff --git a/engines/ags/lib/std/math.h b/engines/ags/lib/std/math.h
index f3e5990dbc..706d9d7c3a 100644
--- a/engines/ags/lib/std/math.h
+++ b/engines/ags/lib/std/math.h
@@ -38,7 +38,7 @@ namespace std {
template<class T>
inline bool isUndefined(T val) {
-return val == FLOAT_UNASSIGNED;
+ return val == FLOAT_UNASSIGNED;
}
} // namespace std
diff --git a/engines/ags/lib/std/memory.h b/engines/ags/lib/std/memory.h
index ae5a1a7161..7efe2c16f6 100644
--- a/engines/ags/lib/std/memory.h
+++ b/engines/ags/lib/std/memory.h
@@ -40,13 +40,13 @@ using unique_ptr = Common::ScopedPtr<T, DL>;
template<class T>
T *memcpy(T *dest, const T *src, size_t n) {
-return (T *)::memcpy(dest, src, n);
+ return (T *)::memcpy(dest, src, n);
}
template<class T>
shared_ptr<T> static_pointer_cast(const shared_ptr<T> &src) {
-T *ptr = src.get();
-return shared_ptr<T>(ptr);
+ T *ptr = src.get();
+ return shared_ptr<T>(ptr);
}
} // namespace std
diff --git a/engines/ags/lib/std/queue.h b/engines/ags/lib/std/queue.h
index b0803ba527..2dfe76ccb0 100644
--- a/engines/ags/lib/std/queue.h
+++ b/engines/ags/lib/std/queue.h
@@ -36,27 +36,27 @@ using queue = Common::Queue<T>;
template<class T, class Container = vector<T>, class Comparitor = typename Common::Less<T> >
class priority_queue {
private:
-Container _container;
-Comparitor _comparitor;
+ Container _container;
+ Comparitor _comparitor;
public:
-priority_queue() {}
+ priority_queue() {}
-bool empty() const {
- return _container.empty();
-}
+ bool empty() const {
+ return _container.empty();
+ }
-const T &top() const {
- return _container.front();
-}
+ const T &top() const {
+ return _container.front();
+ }
-void push(const T &item) {
- _container.push_back(item);
- Common::sort(_container.begin(), _container.end(), _comparitor);
-}
+ void push(const T &item) {
+ _container.push_back(item);
+ Common::sort(_container.begin(), _container.end(), _comparitor);
+ }
-void pop() {
- _container.remove_at(0);
-}
+ void pop() {
+ _container.remove_at(0);
+ }
};
} // namespace std
diff --git a/engines/ags/lib/std/set.h b/engines/ags/lib/std/set.h
index bfa1b7e511..0d5b941d92 100644
--- a/engines/ags/lib/std/set.h
+++ b/engines/ags/lib/std/set.h
@@ -34,58 +34,58 @@ namespace std {
template<class T, class Comparitor = Common::Less<T> >
class set : public Common::SortedArray<T, const T &> {
private:
-static int ComparatorFn(const T &a, const T &b) {
- return Comparitor().operator()(a, b) ? -1 : 0;
-}
-public:
-struct Entry {
- const T &_value;
- Entry(const T &item) : _value(item) {
+ static int ComparatorFn(const T &a, const T &b) {
+ return Comparitor().operator()(a, b) ? -1 : 0;
}
-};
public:
-using iterator = typename Common::SortedArray<T, const T &>::iterator;
-using const_iterator = typename Common::SortedArray<T, const T &>::const_iterator;
+ struct Entry {
+ const T &_value;
+ Entry(const T &item) : _value(item) {
+ }
+ };
+public:
+ using iterator = typename Common::SortedArray<T, const T &>::iterator;
+ using const_iterator = typename Common::SortedArray<T, const T &>::const_iterator;
-/**
- * Constructor
- */
-set() : Common::SortedArray<T, const T & >(ComparatorFn) {}
+ /**
+ * Constructor
+ */
+ set() : Common::SortedArray<T, const T & >(ComparatorFn) {}
-/**
- * Locate an item in the set
- */
-iterator find(const T &item) {
- iterator it;
- for (it = this->begin(); it != this->end() && *it != item; ++it) {
+ /**
+ * Locate an item in the set
+ */
+ iterator find(const T &item) {
+ iterator it;
+ for (it = this->begin(); it != this->end() && *it != item; ++it) {
+ }
+
+ return it;
}
- return it;
-}
+ /**
+ * Insert an element at the sorted position.
+ */
+ Entry insert(const T &item) {
+ Common::SortedArray<T, const T &>::insert(item);
+ return Entry(item);
+ }
-/**
- * Insert an element at the sorted position.
- */
-Entry insert(const T &item) {
- Common::SortedArray<T, const T &>::insert(item);
- return Entry(item);
-}
+ /**
+ * Returns the number of keys that match the specified key
+ */
+ size_t count(const T item) const {
+ size_t total = 0;
+ for (const_iterator it = this->begin(); it != this->end(); ++it) {
+ if (*it == item)
+ ++total;
+ else if (!ComparatorFn(item, *it))
+ // Passed beyond possibility of matches
+ break;
+ }
-/**
- * Returns the number of keys that match the specified key
- */
-size_t count(const T item) const {
- size_t total = 0;
- for (const_iterator it = this->begin(); it != this->end(); ++it) {
- if (*it == item)
- ++total;
- else if (!ComparatorFn(item, *it))
- // Passed beyond possibility of matches
- break;
+ return total;
}
-
- return total;
-}
};
} // namespace std
diff --git a/engines/ags/lib/std/type_traits.h b/engines/ags/lib/std/type_traits.h
index 9edac398d0..cc33200a82 100644
--- a/engines/ags/lib/std/type_traits.h
+++ b/engines/ags/lib/std/type_traits.h
@@ -31,17 +31,17 @@ namespace std {
// STRUCT TEMPLATE remove_extent
template <class _Ty>
struct remove_extent { // remove array extent
-using type = _Ty;
+ using type = _Ty;
};
template <class _Ty, size_t _Ix>
struct remove_extent<_Ty[_Ix]> {
-using type = _Ty;
+ using type = _Ty;
};
template <class _Ty>
struct remove_extent<_Ty[]> {
-using type = _Ty;
+ using type = _Ty;
};
template <class _Ty>
diff --git a/engines/ags/lib/std/unordered_set.h b/engines/ags/lib/std/unordered_set.h
index 3f92ecbb5c..12a73026dc 100644
--- a/engines/ags/lib/std/unordered_set.h
+++ b/engines/ags/lib/std/unordered_set.h
@@ -36,53 +36,53 @@ namespace std {
template <class T, class Hash = Common::Hash<T>, class Pred = Common::EqualTo<T> >
class unordered_set : public Common::Array<T> {
private:
-Hash _hash;
-Pred _comparitor;
+ Hash _hash;
+ Pred _comparitor;
+ public:
+ struct Entry {
+ const T &_value;
+ Entry(const T &item) : _value(item) {}
+ };
public:
-struct Entry {
- const T &_value;
- Entry(const T &item) : _value(item) {}
-};
-public:
-using iterator = typename Common::Array<T>::iterator;
-using const_iterator = typename Common::Array<T>::const_iterator;
+ using iterator = typename Common::Array<T>::iterator;
+ using const_iterator = typename Common::Array<T>::const_iterator;
-unordered_set() {}
+ unordered_set() {}
-/**
- * Locate an item in the set
- */
-iterator find(const T &item) {
- iterator it;
- for (it = this->begin(); it != this->end() && *it != item; ++it) {
+ /**
+ * Locate an item in the set
+ */
+ iterator find(const T &item) {
+ iterator it;
+ for (it = this->begin(); it != this->end() && *it != item; ++it) {
+ }
+
+ return it;
}
- return it;
-}
+ /**
+ * Adds an item
+ */
+ Entry insert(const T &item) {
+ this->push_back(item);
+ return Entry(item);
+ }
-/**
- * Adds an item
- */
-Entry insert(const T &item) {
- this->push_back(item);
- return Entry(item);
-}
+ /**
+ * Returns the number of keys that match the specified key
+ */
+ size_t count(const T item) const {
+ size_t total = 0;
+ for (const_iterator it = this->begin(); it != this->end(); ++it) {
+ if (*it == item)
+ ++total;
+ else if (!_comparitor(item, *it))
+ // Passed beyond possibility of matches
+ break;
+ }
-/**
- * Returns the number of keys that match the specified key
- */
-size_t count(const T item) const {
- size_t total = 0;
- for (const_iterator it = this->begin(); it != this->end(); ++it) {
- if (*it == item)
- ++total;
- else if (!_comparitor(item, *it))
- // Passed beyond possibility of matches
- break;
+ return total;
}
-
- return total;
-}
};
} // namespace std
diff --git a/engines/ags/lib/std/utility.h b/engines/ags/lib/std/utility.h
index 7ad169d04c..41c43d09ac 100644
--- a/engines/ags/lib/std/utility.h
+++ b/engines/ags/lib/std/utility.h
@@ -28,23 +28,23 @@ namespace std {
template<class T1, class T2>
struct pair {
-T1 first;
-T2 second;
+ T1 first;
+ T2 second;
-pair() {
-}
-pair(T1 first_, T2 second_) : first(first_), second(second_) {
-}
+ pair() {
+ }
+ pair(T1 first_, T2 second_) : first(first_), second(second_) {
+ }
};
template< class T1, class T2 >
pair<T1, T2> make_pair(T1 first, T2 second) {
-return pair<T1, T2>(first, second);
+ return pair<T1, T2>(first, second);
}
template<class T>
T move(const T &v) {
-return v;
+ return v;
}
} // namespace std
diff --git a/engines/ags/lib/std/vector.h b/engines/ags/lib/std/vector.h
index 76e5b9ea5a..0c5b01f352 100644
--- a/engines/ags/lib/std/vector.h
+++ b/engines/ags/lib/std/vector.h
@@ -31,173 +31,173 @@ namespace std {
template<class T>
class vector : public Common::Array<T> {
public:
-struct reverse_iterator {
-private:
- vector<T> *_owner;
- int _index;
+ struct reverse_iterator {
+ private:
+ vector<T> *_owner;
+ int _index;
+ public:
+ reverse_iterator(vector<T> *owner, int index) : _owner(owner), _index(index) {
+ }
+ reverse_iterator() : _owner(0), _index(-1) {
+ }
+
+ T &operator*() {
+ return (*_owner)[_index];
+ }
+
+ reverse_iterator &operator++() {
+ --_index;
+ return *this;
+ }
+
+ bool operator==(const reverse_iterator &rhs) {
+ return _owner == rhs._owner && _index == rhs._index;
+ }
+ bool operator!=(const reverse_iterator &rhs) {
+ return !operator==(rhs);
+ }
+ };
+
+ struct const_reverse_iterator {
+ private:
+ const vector<T> *_owner;
+ int _index;
+ public:
+ const_reverse_iterator(const vector<T> *owner, int index) : _owner(owner), _index(index) {
+ }
+ const_reverse_iterator() : _owner(0), _index(-1) {
+ }
+
+ const T operator*() const {
+ return (*_owner)[_index];
+ }
+
+ const_reverse_iterator &operator++() {
+ --_index;
+ return *this;
+ }
+
+ bool operator==(const const_reverse_iterator &rhs) {
+ return _owner == rhs._owner && _index == rhs._index;
+ }
+ bool operator!=(const const_reverse_iterator &rhs) {
+ return !operator==(rhs);
+ }
+ };
+
+ using iterator = typename Common::Array<T>::iterator;
+ using const_iterator = typename Common::Array<T>::const_iterator;
public:
- reverse_iterator(vector<T> *owner, int index) : _owner(owner), _index(index) {
+ typedef T reference;
+ typedef const T const_reference;
+
+ vector() : Common::Array<T>() {
}
- reverse_iterator() : _owner(0), _index(-1) {
+ vector(size_t newSize) : Common::Array<T>() {
+ Common::Array<T>::resize(newSize);
+ }
+ vector(size_t newSize, const T elem) {
+ resize(newSize, elem);
}
- T &operator*() {
- return (*_owner)[_index];
+ iterator erase(iterator pos) {
+ return Common::Array<T>::erase(pos);
}
- reverse_iterator &operator++() {
- --_index;
- return *this;
+ iterator erase(iterator first,
+ iterator last) {
+ Common::copy(last, this->_storage + this->_size, first);
+
+ int count = (last - first);
+ this->_size -= count;
+
+ // We also need to destroy the objects beyond the new size
+ for (uint idx = this->_size; idx < (this->_size + count); ++idx)
+ this->_storage[idx].~T();
+
+ return first;
}
- bool operator==(const reverse_iterator &rhs) {
- return _owner == rhs._owner && _index == rhs._index;
+ void swap(vector &arr) {
+ SWAP(this->_capacity, arr._capacity);
+ SWAP(this->_size, arr._size);
+ SWAP(this->_storage, arr._storage);
}
- bool operator!=(const reverse_iterator &rhs) {
- return !operator==(rhs);
+
+ /**
+ * Rotates the array so that the item pointed to by the iterator becomes
+ * the first item, and the predeceding item becomes the last one
+ */
+ void rotate(iterator it) {
+ if (it != Common::Array<T>::end()) {
+ size_t count = it - Common::Array<T>::begin();
+ for (size_t ctr = 0; ctr < count; ++ctr) {
+ Common::Array<T>::push_back(Common::Array<T>::front());
+ Common::Array<T>::remove_at(0);
+ }
+ }
}
-};
-struct const_reverse_iterator {
-private:
- const vector<T> *_owner;
- int _index;
-public:
- const_reverse_iterator(const vector<T> *owner, int index) : _owner(owner), _index(index) {
+ const_iterator cbegin() {
+ return this->begin();
}
- const_reverse_iterator() : _owner(0), _index(-1) {
+ const_iterator cend() {
+ return this->end();
}
-
- const T operator*() const {
- return (*_owner)[_index];
+ reverse_iterator rbegin() {
+ return reverse_iterator(this, (int)Common::Array<T>::size() - 1);
+ }
+ reverse_iterator rend() {
+ return reverse_iterator(this, -1);
+ }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(this, (int)Common::Array<T>::size() - 1);
+ }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(this, -1);
}
- const_reverse_iterator &operator++() {
- --_index;
- return *this;
+ void pop_front() {
+ Common::Array<T>::remove_at(0);
}
- bool operator==(const const_reverse_iterator &rhs) {
- return _owner == rhs._owner && _index == rhs._index;
+ void resize(size_t newSize) {
+ Common::Array<T>::resize(newSize);
}
- bool operator!=(const const_reverse_iterator &rhs) {
- return !operator==(rhs);
+ void resize(size_t newSize, const T elem) {
+ size_t oldSize = Common::Array<T>::size();
+ resize(newSize);
+ for (size_t idx = oldSize; idx < newSize; ++idx)
+ this->operator[](idx) = elem;
}
-};
-using iterator = typename Common::Array<T>::iterator;
-using const_iterator = typename Common::Array<T>::const_iterator;
-public:
-typedef T reference;
-typedef const T const_reference;
-
-vector() : Common::Array<T>() {
-}
-vector(size_t newSize) : Common::Array<T>() {
- Common::Array<T>::resize(newSize);
-}
-vector(size_t newSize, const T elem) {
- resize(newSize, elem);
-}
-
-iterator erase(iterator pos) {
- return Common::Array<T>::erase(pos);
-}
-
-iterator erase(iterator first,
- iterator last) {
- Common::copy(last, this->_storage + this->_size, first);
-
- int count = (last - first);
- this->_size -= count;
-
- // We also need to destroy the objects beyond the new size
- for (uint idx = this->_size; idx < (this->_size + count); ++idx)
- this->_storage[idx].~T();
-
- return first;
-}
-
-void swap(vector &arr) {
- SWAP(this->_capacity, arr._capacity);
- SWAP(this->_size, arr._size);
- SWAP(this->_storage, arr._storage);
-}
-
-/**
- * Rotates the array so that the item pointed to by the iterator becomes
- * the first item, and the predeceding item becomes the last one
- */
-void rotate(iterator it) {
- if (it != Common::Array<T>::end()) {
- size_t count = it - Common::Array<T>::begin();
- for (size_t ctr = 0; ctr < count; ++ctr) {
- Common::Array<T>::push_back(Common::Array<T>::front());
- Common::Array<T>::remove_at(0);
- }
+ T at(size_t index) const {
+ return (*this)[index];
}
-}
-
-const_iterator cbegin() {
- return this->begin();
-}
-const_iterator cend() {
- return this->end();
-}
-reverse_iterator rbegin() {
- return reverse_iterator(this, (int)Common::Array<T>::size() - 1);
-}
-reverse_iterator rend() {
- return reverse_iterator(this, -1);
-}
-const_reverse_iterator rbegin() const {
- return const_reverse_iterator(this, (int)Common::Array<T>::size() - 1);
-}
-const_reverse_iterator rend() const {
- return const_reverse_iterator(this, -1);
-}
-
-void pop_front() {
- Common::Array<T>::remove_at(0);
-}
-
-void resize(size_t newSize) {
- Common::Array<T>::resize(newSize);
-}
-void resize(size_t newSize, const T elem) {
- size_t oldSize = Common::Array<T>::size();
- resize(newSize);
- for (size_t idx = oldSize; idx < newSize; ++idx)
- this->operator[](idx) = elem;
-}
-
-T at(size_t index) const {
- return (*this)[index];
-}
-
-/**
- * Adds an item to the array
- */
-void insert(const T &element) {
- Common::Array<T>::push_back(element);
-}
-/**
- * Adds an item to the array at a specified index
- */
-void insert(iterator pos, const T &element) {
- Common::Array<T>::insert(pos, element);
-}
+ /**
+ * Adds an item to the array
+ */
+ void insert(const T &element) {
+ Common::Array<T>::push_back(element);
+ }
-/**
- * Adds a range of items at the specified position in the array
- */
-void insert(iterator position, const_iterator first, const_iterator last) {
- int destIndex = position - this->begin();
- for (; first != last; ++first) {
- this->insert_at(destIndex++, *first);
+ /**
+ * Adds an item to the array at a specified index
+ */
+ void insert(iterator pos, const T &element) {
+ Common::Array<T>::insert(pos, element);
+ }
+
+ /**
+ * Adds a range of items at the specified position in the array
+ */
+ void insert(iterator position, const_iterator first, const_iterator last) {
+ int destIndex = position - this->begin();
+ for (; first != last; ++first) {
+ this->insert_at(destIndex++, *first);
+ }
}
-}
};
} // namespace std
diff --git a/engines/ags/lib/std/xtr1common.h b/engines/ags/lib/std/xtr1common.h
index f8813c7583..c17c0ba663 100644
--- a/engines/ags/lib/std/xtr1common.h
+++ b/engines/ags/lib/std/xtr1common.h
@@ -29,12 +29,12 @@ namespace std {
// STRUCT TEMPLATE conditional
template <bool _Test, class _Ty1, class _Ty2>
struct conditional { // Choose _Ty1 if _Test is true, and _Ty2 otherwise
-using type = _Ty1;
+ using type = _Ty1;
};
template <class _Ty1, class _Ty2>
struct conditional<false, _Ty1, _Ty2> {
-using type = _Ty2;
+ using type = _Ty2;
};
template <bool _Test, class _Ty1, class _Ty2>
diff --git a/engines/ags/lib/std/xutility.h b/engines/ags/lib/std/xutility.h
index da838abdb7..519db3c054 100644
--- a/engines/ags/lib/std/xutility.h
+++ b/engines/ags/lib/std/xutility.h
@@ -31,9 +31,9 @@ namespace std {
template <class T>
void reverse(T *First, T *Last) {
-for (--Last; First < Last; ++First, --Last) {
- SWAP(*First, *Last);
-}
+ for (--Last; First < Last; ++First, --Last) {
+ SWAP(*First, *Last);
+ }
}
} // namespace std
Commit: 7a1ee192e2663e53c8e7edbb1a3d59829f96f7dd
https://github.com/scummvm/scummvm/commit/7a1ee192e2663e53c8e7edbb1a3d59829f96f7dd
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:34-07:00
Commit Message:
AGS: Fixup character's view loop in update, prevent having no frame
>From upstream 2ac1b258db203b62ba0613c979d7a092b51e441f
Changed paths:
engines/ags/engine/ac/character_info_engine.cpp
diff --git a/engines/ags/engine/ac/character_info_engine.cpp b/engines/ags/engine/ac/character_info_engine.cpp
index 3fc262c0c6..560f334a3f 100644
--- a/engines/ags/engine/ac/character_info_engine.cpp
+++ b/engines/ags/engine/ac/character_info_engine.cpp
@@ -76,10 +76,15 @@ void CharacterInfo::UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, in
return; // must be careful not to screw things up
}
- // Make sure it doesn't flash up a blue cup
- if (view < 0);
- else if (loop >= _G(views)[view].numLoops)
- loop = 0;
+ // Fixup character's view when possible
+ if (view >= 0 &&
+ (loop >= _G(views)[view].numLoops || frame >= _G(views)[view].loops[loop].numFrames)) {
+ for (loop = 0;
+ (loop < _G(views)[view].numLoops) && (_G(views)[view].loops[loop].numFrames == 0); ++loop) {
+ }
+ if (loop == _G(views)[view].numLoops)
+ quitprintf("!Character %s is assigned view %d that has no frames!", name, view);
+ }
int doing_nothing = 1;
Commit: 69157077cff2d7c3f1a2019d044a120d579b8d5f
https://github.com/scummvm/scummvm/commit/69157077cff2d7c3f1a2019d044a120d579b8d5f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:35-07:00
Commit Message:
AGS: Fixed Path::GetParent (now it actually works)
>From upstream a72e45f6ebb19e9da96cbe2d621f86ac57bffa8a
Changed paths:
engines/ags/shared/util/path.cpp
engines/ags/shared/util/path.h
diff --git a/engines/ags/shared/util/path.cpp b/engines/ags/shared/util/path.cpp
index 56b894ea5c..b19ca3ecd6 100644
--- a/engines/ags/shared/util/path.cpp
+++ b/engines/ags/shared/util/path.cpp
@@ -70,6 +70,16 @@ bool IsFileOrDir(const String &filename) {
return ags_path_exists(fixed_path.GetCStr()) != 0;
}
+String GetParent(const String &path) {
+ const char *cstr = path.GetCStr();
+ const char *ptr_end = cstr + path.GetLength();
+ for (const char *ptr = ptr_end; ptr > cstr; --ptr) {
+ if (*ptr == '/' || *ptr == PATH_ALT_SEPARATOR)
+ return String(cstr, ptr - cstr);
+ }
+ return ".";
+}
+
String GetFilename(const String &path) {
return get_filename(path.GetCStr());
}
diff --git a/engines/ags/shared/util/path.h b/engines/ags/shared/util/path.h
index 664beb8754..44c99dee11 100644
--- a/engines/ags/shared/util/path.h
+++ b/engines/ags/shared/util/path.h
@@ -51,7 +51,8 @@ bool IsFile(const String &filename);
// Tells if the given path is file or directory;
// may be used to check if it's valid to use
bool IsFileOrDir(const String &filename);
-// Returns filename part out of the longer path
+// Returns parent directory of the given path;
+// returns "." (current dir) if the path does not contain a parent segment
String GetFilename(const String &path);
// Returns file's extension; file may be a fully qualified path too
String GetFileExtension(const String &path);
Commit: 5e37a5515ba10088e0de1add06c2db553618b1b4
https://github.com/scummvm/scummvm/commit/5e37a5515ba10088e0de1add06c2db553618b1b4
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:35-07:00
Commit Message:
AGS: Implemented GetFiles and GetDirs through the same algorithm
>From upstream 187b8fde1350575e3d848355cba3aba928285c22
Changed paths:
engines/ags/shared/util/directory.cpp
engines/ags/shared/util/directory.h
diff --git a/engines/ags/shared/util/directory.cpp b/engines/ags/shared/util/directory.cpp
index aea9cd7086..2b0dccfd04 100644
--- a/engines/ags/shared/util/directory.cpp
+++ b/engines/ags/shared/util/directory.cpp
@@ -89,6 +89,27 @@ String GetCurrentDirectory() {
#endif
}
+static bool GetFilesImpl(const String &dir_path, std::vector<String> &files, bool isDirectories) {
+ Common::FSNode fsNode(dir_path);
+ Common::FSList fsList;
+
+ fsNode.getChildren(fsList,
+ isDirectories ? Common::FSNode::kListDirectoriesOnly :
+ Common::FSNode::kListFilesOnly);
+
+ for (uint i = 0; i < fsList.size(); ++i)
+ files.push_back(fsList[i].getName());
+ return true;
+}
+
+bool GetDirs(const String &dir_path, std::vector<String> &dirs) {
+ return GetFilesImpl(dir_path, dirs, true);
+}
+
+bool GetFiles(const String &dir_path, std::vector<String> &files) {
+ return GetFilesImpl(dir_path, files, false);
+}
+
} // namespace Directory
} // namespace Shared
diff --git a/engines/ags/shared/util/directory.h b/engines/ags/shared/util/directory.h
index 0093193da2..80df2f0d16 100644
--- a/engines/ags/shared/util/directory.h
+++ b/engines/ags/shared/util/directory.h
@@ -50,6 +50,11 @@ String SetCurrentDirectory(const String &path);
// Gets current working directory
String GetCurrentDirectory();
+// Get list of subdirs found in the given directory
+bool GetDirs(const String &dir_path, std::vector<String> &dirs);
+// Get list of files found in the given directory
+bool GetFiles(const String &dir_path, std::vector<String> &files);
+
} // namespace Directory
} // namespace Shared
Commit: 00ade063b9ab75941562e616cc679547d0100a71
https://github.com/scummvm/scummvm/commit/00ade063b9ab75941562e616cc679547d0100a71
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:35-07:00
Commit Message:
AGS: In File api functions replaced quit with a warning on error
>From upstream b703e7d25041e1b6bf99b76a89ca422351e04ace
Changed paths:
engines/ags/engine/ac/file.cpp
engines/ags/engine/ac/global_file.cpp
diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp
index 9ed36878a2..105a2c3ca4 100644
--- a/engines/ags/engine/ac/file.cpp
+++ b/engines/ags/engine/ac/file.cpp
@@ -118,12 +118,12 @@ void File_ReadRawLine(sc_File *fil, char *buffer) {
int i = 0;
while (i < _G(MAXSTRLEN) - 1) {
buffer[i] = in->ReadInt8();
- if (buffer[i] == 13) {
+ if (buffer[i] == '\r') {
// CR -- skip LF and abort
in->ReadInt8();
break;
}
- if (buffer[i] == 10) // LF only -- abort
+ if (buffer[i] == '\n') // LF only -- abort
break;
if (in->EOS()) // EOF -- abort
break;
@@ -148,9 +148,11 @@ const char *File_ReadStringBack(sc_File *fil) {
return CreateNewScriptString("");
}
- int lle = in->ReadInt32();
- if ((lle >= 20000) || (lle < 1))
- quit("!File.ReadStringBack: file was not written by WriteString");
+ size_t lle = (uint32_t)in->ReadInt32();
+ if (lle == 0) {
+ debug_script_warn("File.ReadStringBack: file was not written by WriteString");
+ return CreateNewScriptString("");
+ }
char *retVal = (char *)malloc(lle);
in->Read(retVal, lle);
diff --git a/engines/ags/engine/ac/global_file.cpp b/engines/ags/engine/ac/global_file.cpp
index b18627ce03..204cd23771 100644
--- a/engines/ags/engine/ac/global_file.cpp
+++ b/engines/ags/engine/ac/global_file.cpp
@@ -101,14 +101,15 @@ void FileClose(int32_t handle) {
}
void FileWrite(int32_t handle, const char *towrite) {
Stream *out = get_valid_file_stream_from_handle(handle, "FileWrite");
- out->WriteInt32(strlen(towrite) + 1);
- out->Write(towrite, strlen(towrite) + 1);
+ size_t len = strlen(towrite);
+ out->WriteInt32(len + 1); // write with null-terminator
+ out->Write(towrite, len + 1);
}
void FileWriteRawLine(int32_t handle, const char *towrite) {
Stream *out = get_valid_file_stream_from_handle(handle, "FileWriteRawLine");
out->Write(towrite, strlen(towrite));
- out->WriteInt8(13);
- out->WriteInt8(10);
+ out->WriteInt8('\r');
+ out->WriteInt8('\n');
}
void FileRead(int32_t handle, char *toread) {
VALIDATE_STRING(toread);
@@ -117,10 +118,16 @@ void FileRead(int32_t handle, char *toread) {
toread[0] = 0;
return;
}
- int lle = in->ReadInt32();
- if ((lle >= 200) | (lle < 1)) quit("!FileRead: file was not written by FileWrite");
+
+ size_t lle = (uint32_t)in->ReadInt32();
+ // This tests for the legacy string (limited by 200 chars)
+ if ((lle >= 200) | (lle < 1)) {
+ debug_script_warn("FileRead: file was not written by FileWrite");
+ return;
+ }
in->Read(toread, lle);
}
+
int FileIsEOF(int32_t handle) {
Stream *stream = get_valid_file_stream_from_handle(handle, "FileIsEOF");
if (stream->EOS())
@@ -152,26 +159,32 @@ int FileReadInt(int32_t handle) {
Stream *in = get_valid_file_stream_from_handle(handle, "FileReadInt");
if (in->EOS())
return -1;
- if (in->ReadInt8() != 'I')
- quit("!FileReadInt: File read back in wrong order");
+ if (in->ReadInt8() != 'I') {
+ debug_script_warn("FileReadInt: File read back in wrong order");
+ return -1;
+ }
+
return in->ReadInt32();
}
+
char FileReadRawChar(int32_t handle) {
Stream *in = get_valid_file_stream_from_handle(handle, "FileReadRawChar");
if (in->EOS())
return -1;
return in->ReadInt8();
}
+
int FileReadRawInt(int32_t handle) {
Stream *in = get_valid_file_stream_from_handle(handle, "FileReadRawInt");
if (in->EOS())
return -1;
return in->ReadInt32();
}
+
void FileWriteRawChar(int32_t handle, int chartoWrite) {
Stream *out = get_valid_file_stream_from_handle(handle, "FileWriteRawChar");
if ((chartoWrite < 0) || (chartoWrite > 255))
- quit("!FileWriteRawChar: can only write values 0-255");
+ debug_script_warn("!FileWriteRawChar: can only write values 0-255");
out->WriteInt8(chartoWrite);
}
Commit: 5ccb07acf9d63f536e349120c07ee84bfebf8f90
https://github.com/scummvm/scummvm/commit/5ccb07acf9d63f536e349120c07ee84bfebf8f90
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:36-07:00
Commit Message:
AGS: implemented bool Room.Exists(int room)
>From upstream d676baaea0860ef1737019452d8e97b4aee12526
Changed paths:
engines/ags/engine/ac/room.cpp
engines/ags/engine/ac/room.h
engines/ags/engine/script/script_api.h
engines/ags/plugins/core/room.cpp
engines/ags/plugins/core/room.h
diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp
index 9305c69a81..9cbf56cd7e 100644
--- a/engines/ags/engine/ac/room.cpp
+++ b/engines/ags/engine/ac/room.cpp
@@ -166,6 +166,11 @@ const char *Room_GetMessages(int index) {
return CreateNewScriptString(buffer);
}
+bool Room_Exists(int room) {
+ String room_filename;
+ room_filename.Format("room%d.crm", room);
+ return _GP(AssetMgr)->DoesAssetExist(room_filename);
+}
//=============================================================================
@@ -1158,25 +1163,30 @@ RuntimeScriptValue Sc_RoomProcessClick(const RuntimeScriptValue *params, int32_t
API_SCALL_VOID_PINT3(RoomProcessClick);
}
+RuntimeScriptValue Sc_Room_Exists(const RuntimeScriptValue *params, int32_t param_count) {
+ API_SCALL_BOOL_PINT(Room_Exists);
+}
+
void RegisterRoomAPI() {
ccAddExternalStaticFunction("Room::GetDrawingSurfaceForBackground^1", Sc_Room_GetDrawingSurfaceForBackground);
- ccAddExternalStaticFunction("Room::GetProperty^1", Sc_Room_GetProperty);
- ccAddExternalStaticFunction("Room::GetTextProperty^1", Sc_Room_GetTextProperty);
- ccAddExternalStaticFunction("Room::SetProperty^2", Sc_Room_SetProperty);
- ccAddExternalStaticFunction("Room::SetTextProperty^2", Sc_Room_SetTextProperty);
- ccAddExternalStaticFunction("Room::ProcessClick^3", Sc_RoomProcessClick);
- ccAddExternalStaticFunction("ProcessClick", Sc_RoomProcessClick);
- ccAddExternalStaticFunction("Room::get_BottomEdge", Sc_Room_GetBottomEdge);
- ccAddExternalStaticFunction("Room::get_ColorDepth", Sc_Room_GetColorDepth);
- ccAddExternalStaticFunction("Room::get_Height", Sc_Room_GetHeight);
- ccAddExternalStaticFunction("Room::get_LeftEdge", Sc_Room_GetLeftEdge);
- ccAddExternalStaticFunction("Room::geti_Messages", Sc_Room_GetMessages);
- ccAddExternalStaticFunction("Room::get_MusicOnLoad", Sc_Room_GetMusicOnLoad);
- ccAddExternalStaticFunction("Room::get_ObjectCount", Sc_Room_GetObjectCount);
- ccAddExternalStaticFunction("Room::get_RightEdge", Sc_Room_GetRightEdge);
- ccAddExternalStaticFunction("Room::get_TopEdge", Sc_Room_GetTopEdge);
- ccAddExternalStaticFunction("Room::get_Width", Sc_Room_GetWidth);
+ ccAddExternalStaticFunction("Room::GetProperty^1", Sc_Room_GetProperty);
+ ccAddExternalStaticFunction("Room::GetTextProperty^1", Sc_Room_GetTextProperty);
+ ccAddExternalStaticFunction("Room::SetProperty^2", Sc_Room_SetProperty);
+ ccAddExternalStaticFunction("Room::SetTextProperty^2", Sc_Room_SetTextProperty);
+ ccAddExternalStaticFunction("Room::ProcessClick^3", Sc_RoomProcessClick);
+ ccAddExternalStaticFunction("ProcessClick", Sc_RoomProcessClick);
+ ccAddExternalStaticFunction("Room::get_BottomEdge", Sc_Room_GetBottomEdge);
+ ccAddExternalStaticFunction("Room::get_ColorDepth", Sc_Room_GetColorDepth);
+ ccAddExternalStaticFunction("Room::get_Height", Sc_Room_GetHeight);
+ ccAddExternalStaticFunction("Room::get_LeftEdge", Sc_Room_GetLeftEdge);
+ ccAddExternalStaticFunction("Room::geti_Messages", Sc_Room_GetMessages);
+ ccAddExternalStaticFunction("Room::get_MusicOnLoad", Sc_Room_GetMusicOnLoad);
+ ccAddExternalStaticFunction("Room::get_ObjectCount", Sc_Room_GetObjectCount);
+ ccAddExternalStaticFunction("Room::get_RightEdge", Sc_Room_GetRightEdge);
+ ccAddExternalStaticFunction("Room::get_TopEdge", Sc_Room_GetTopEdge);
+ ccAddExternalStaticFunction("Room::get_Width", Sc_Room_GetWidth);
+ ccAddExternalStaticFunction("Room::Exists", Sc_Room_Exists);
}
} // namespace AGS3
diff --git a/engines/ags/engine/ac/room.h b/engines/ags/engine/ac/room.h
index 2e6116fa2b..cef464acd0 100644
--- a/engines/ags/engine/ac/room.h
+++ b/engines/ags/engine/ac/room.h
@@ -43,6 +43,7 @@ int Room_GetMusicOnLoad();
const char *Room_GetTextProperty(const char *property);
int Room_GetProperty(const char *property);
const char *Room_GetMessages(int index);
+bool Room_Exists(int room);
RuntimeScriptValue Sc_Room_GetProperty(const RuntimeScriptValue *params, int32_t param_count);
//=============================================================================
diff --git a/engines/ags/engine/script/script_api.h b/engines/ags/engine/script/script_api.h
index 0ffbe8a705..18bac43cb9 100644
--- a/engines/ags/engine/script/script_api.h
+++ b/engines/ags/engine/script/script_api.h
@@ -285,6 +285,10 @@ inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *f
ASSERT_PARAM_COUNT(FUNCTION, 1); \
return RuntimeScriptValue().SetInt32AsBool(FUNCTION((P1CLASS*)params[0].Ptr))
+#define API_SCALL_BOOL_PINT(FUNCTION) \
+ ASSERT_PARAM_COUNT(FUNCTION, 1); \
+ return RuntimeScriptValue().SetInt32AsBool(FUNCTION(params[0].IValue))
+
#define API_SCALL_BOOL_POBJ_PINT(FUNCTION, P1CLASS) \
ASSERT_PARAM_COUNT(FUNCTION, 2); \
return RuntimeScriptValue().SetInt32AsBool(FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue))
diff --git a/engines/ags/plugins/core/room.cpp b/engines/ags/plugins/core/room.cpp
index 4917c05685..f98c56279f 100644
--- a/engines/ags/plugins/core/room.cpp
+++ b/engines/ags/plugins/core/room.cpp
@@ -101,6 +101,11 @@ void Room::GetWidth(ScriptMethodParams ¶ms) {
params._result = AGS3::Room_GetWidth();
}
+void Room::RoomExists(ScriptMethodParams ¶ms) {
+ PARAMS1(int, room);
+ params._result = AGS3::Room_Exists(room);
+}
+
} // namespace Core
} // namespace Plugins
} // namespace AGS3
diff --git a/engines/ags/plugins/core/room.h b/engines/ags/plugins/core/room.h
index f891e9f77e..d617953549 100644
--- a/engines/ags/plugins/core/room.h
+++ b/engines/ags/plugins/core/room.h
@@ -48,6 +48,7 @@ public:
void GetRightEdge(ScriptMethodParams ¶ms);
void GetTopEdge(ScriptMethodParams ¶ms);
void GetWidth(ScriptMethodParams ¶ms);
+ void RoomExists(ScriptMethodParams ¶ms);
};
} // namespace Core
Commit: 47928c39aaf1a3b8523a031fbea02fc34b6103e4
https://github.com/scummvm/scummvm/commit/47928c39aaf1a3b8523a031fbea02fc34b6103e4
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:36-07:00
Commit Message:
AGS: changed Object.SetView default loop & frame values to 0
>From upstream eb376e63f95b09fd75ca7f96591aca20d0564072
Changed paths:
engines/ags/engine/ac/global_object.cpp
engines/ags/engine/ac/object.cpp
diff --git a/engines/ags/engine/ac/global_object.cpp b/engines/ags/engine/ac/global_object.cpp
index 7d00eeace5..39e424ef3d 100644
--- a/engines/ags/engine/ac/global_object.cpp
+++ b/engines/ags/engine/ac/global_object.cpp
@@ -153,13 +153,19 @@ void SetObjectView(int obn, int vii) {
void SetObjectFrame(int obn, int viw, int lop, int fra) {
if (!is_valid_object(obn)) quit("!SetObjectFrame: invalid object number specified");
viw--;
- if (viw >= _GP(game).numviews) quit("!SetObjectFrame: invalid view number used");
- if (_G(views)[viw].numLoops == 0) quit("!SetObjectFrame: specified view has no loops");
- if (lop >= _G(views)[viw].numLoops) quit("!SetObjectFrame: invalid loop number used");
-
+ if (viw < 0 || viw >= _GP(game).numviews) quitprintf("!SetObjectFrame: invalid view number used (%d, range is 0 - %d)", viw, _GP(game).numviews - 1);
+ if (lop < 0 || lop >= _G(views)[viw].numLoops) quitprintf("!SetObjectFrame: invalid loop number used (%d, range is 0 - %d)", lop, _G(views)[viw].numLoops - 1);
+ // AGS < 3.6.0 let user to pass literally any positive invalid frame value by silently reassigning it to zero...
+ if (_GP(game).options[OPT_BASESCRIPTAPI] < kScriptAPI_v360) {
+ if (fra >= _G(views)[viw].loops[lop].numFrames) {
+ debug_script_warn("SetObjectFrame: frame index out of range (%d, must be 0 - %d), set to 0", fra, _G(views)[viw].loops[lop].numFrames - 1);
+ fra = 0;
+ }
+ }
+ if (fra < 0 || fra >= _G(views)[viw].loops[lop].numFrames) quitprintf("!SetObjectFrame: invalid frame number used (%d, range is 0 - %d)", fra, _G(views)[viw].loops[lop].numFrames - 1);
if (viw > UINT16_MAX || lop > UINT16_MAX || fra > UINT16_MAX) {
debug_script_warn("Warning: object's (id %d) view/loop/frame (%d/%d/%d) is outside of internal range (%d/%d/%d), reset to no view",
- obn, viw + 1, lop, fra, UINT16_MAX + 1, UINT16_MAX, UINT16_MAX);
+ obn, viw + 1, lop, fra, UINT16_MAX + 1, UINT16_MAX, UINT16_MAX);
SetObjectGraphic(obn, 0);
return;
}
@@ -169,20 +175,17 @@ void SetObjectFrame(int obn, int viw, int lop, int fra) {
_G(objs)[obn].loop = (uint16_t)lop;
if (fra >= 0)
_G(objs)[obn].frame = (uint16_t)fra;
- if (_G(objs)[obn].loop >= _G(views)[viw].numLoops)
- _G(objs)[obn].loop = 0;
- if (_G(objs)[obn].frame >= _G(views)[viw].loops[_G(objs)[obn].loop].numFrames)
- _G(objs)[obn].frame = 0;
-
// AGS >= 3.2.0 do not let assign an empty loop
// NOTE: pre-3.2.0 games are converting views from ViewStruct272 struct, always has at least 1 frame
if (_G(loaded_game_file_version) >= kGameVersion_320) {
- if (_G(views)[viw].loops[_G(objs)[obn].loop].numFrames == 0)
+ if (_G(views)[viw].loops[lop].numFrames == 0)
quit("!SetObjectFrame: specified loop has no frames");
}
-
+ _G(objs)[obn].view = viw;
+ _G(objs)[obn].loop = lop;
+ _G(objs)[obn].frame = fra;
_G(objs)[obn].cycling = 0;
- int pic = _G(views)[viw].loops[_G(objs)[obn].loop].frames[_G(objs)[obn].frame].pic;
+ int pic = _G(views)[viw].loops[lop].frames[fra].pic;
_G(objs)[obn].num = Math::InRangeOrDef<uint16_t>(pic, 0);
if (pic > UINT16_MAX)
debug_script_warn("Warning: object's (id %d) sprite %d is outside of internal range (%d), reset to 0", obn, pic, UINT16_MAX);
diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp
index d55a27d41f..cc04f39096 100644
--- a/engines/ags/engine/ac/object.cpp
+++ b/engines/ags/engine/ac/object.cpp
@@ -40,6 +40,7 @@
#include "ags/engine/main/game_run.h"
#include "ags/engine/ac/route_finder.h"
#include "ags/engine/gfx/graphics_driver.h"
+#include "ags/shared/ac/view.h"
#include "ags/shared/gfx/bitmap.h"
#include "ags/shared/gfx/gfx_def.h"
#include "ags/engine/script/runtime_script_value.h"
@@ -87,6 +88,16 @@ void Object_RemoveTint(ScriptObject *objj) {
}
void Object_SetView(ScriptObject *objj, int view, int loop, int frame) {
+ if (_GP(game).options[OPT_BASESCRIPTAPI] < kScriptAPI_v360) { // Previous version of SetView had negative loop and frame mean "use latest values"
+ auto &obj = _G(objs)[objj->id];
+ if (loop < 0) loop = obj.loop;
+ if (frame < 0) frame = obj.frame;
+ const int vidx = view - 1;
+ if (vidx < 0 || vidx >= _GP(game).numviews) quit("!Object_SetView: invalid view number used");
+ loop = CLIP(loop, 0, (int)_G(views)[vidx].numLoops - 1);
+ frame = CLIP(frame, 0, (int)_G(views)[vidx].loops[loop].numFrames - 1);
+ }
+
SetObjectFrame(objj->id, view, loop, frame);
}
Commit: 5b4ce2d365a9764afbfdfff3639ae845e5e5fb7e
https://github.com/scummvm/scummvm/commit/5b4ce2d365a9764afbfdfff3639ae845e5e5fb7e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:36-07:00
Commit Message:
AGS: support source rectangle for DrawImage
>From upstream 27e2f431ed892a0dd9bea8c1831846ca0ca493e1
Changed paths:
engines/ags/engine/ac/drawing_surface.cpp
diff --git a/engines/ags/engine/ac/drawing_surface.cpp b/engines/ags/engine/ac/drawing_surface.cpp
index 731faffd66..b2ec3effe0 100644
--- a/engines/ags/engine/ac/drawing_surface.cpp
+++ b/engines/ags/engine/ac/drawing_surface.cpp
@@ -140,56 +140,91 @@ void DrawingSurface_DrawSurface(ScriptDrawingSurface *target, ScriptDrawingSurfa
target->FinishedDrawing();
}
-void DrawingSurface_DrawImage(ScriptDrawingSurface *sds, int xx, int yy, int slot, int trans, int width, int height) {
+void DrawingSurface_DrawImageEx(ScriptDrawingSurface *sds, int dst_x, int dst_y, int slot, int trans, int dst_width, int dst_height,
+ int src_x, int src_y, int src_width, int src_height) {
if ((slot < 0) || (_GP(spriteset)[slot] == nullptr))
quit("!DrawingSurface.DrawImage: invalid sprite slot number specified");
-
if ((trans < 0) || (trans > 100))
quit("!DrawingSurface.DrawImage: invalid transparency setting");
-
- // 100% transparency, don't draw anything
if (trans == 100)
- return;
-
- Bitmap *sourcePic = _GP(spriteset)[slot];
- bool needToFreeBitmap = false;
-
- if (width != SCR_NO_VALUE) {
- // Resize specified
-
- if ((width < 1) || (height < 1))
- return;
-
- sds->SizeToGameResolution(&width, &height);
+ return; // fully transparent
+ if (dst_width < 1 || dst_height < 1 || src_width < 1 || src_height < 1)
+ return; // invalid src or dest rectangles
+
+ // Setup uninitialized arguments; convert coordinates for legacy script mode
+ Bitmap *ds = sds->GetBitmapSurface();
+ Bitmap *src = _GP(spriteset)[slot];
+ if (dst_width == SCR_NO_VALUE) {
+ dst_width = src->GetWidth();
+ } else {
+ sds->SizeToGameResolution(&dst_width);
+ }
+ if (dst_height == SCR_NO_VALUE) {
+ dst_height = src->GetHeight();
+ } else {
+ sds->SizeToGameResolution(&dst_height);
+ }
- // resize the sprite to the requested size
- Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, sourcePic->GetColorDepth());
+ if (src_x == SCR_NO_VALUE) {
+ src_x = 0;
+ }
+ if (src_y == SCR_NO_VALUE) {
+ src_y = 0;
+ }
+ sds->PointToGameResolution(&src_x, &src_y);
+ if (src_width == SCR_NO_VALUE) {
+ src_width = src->GetWidth();
+ } else {
+ sds->SizeToGameResolution(&src_width);
+ }
+ if (src_height == SCR_NO_VALUE) {
+ src_height = src->GetHeight();
+ } else {
+ sds->SizeToGameResolution(&src_height);
+ }
- newPic->StretchBlt(sourcePic,
- RectWH(0, 0, _GP(game).SpriteInfos[slot].Width, _GP(game).SpriteInfos[slot].Height),
- RectWH(0, 0, width, height));
+ if (dst_x >= ds->GetWidth() || dst_x + dst_width <= 0 || dst_y >= ds->GetHeight() || dst_y + dst_height <= 0 ||
+ src_x >= src->GetWidth() || src_x + src_width <= 0 || src_y >= src->GetHeight() || src_y + src_height <= 0)
+ return; // source or destination rects lie completely off surface
+ // Clamp the source rect to the valid limits to prevent exceptions (ignore dest, bitmap drawing deals with that)
+ Math::ClampLength(src_x, src_width, 0, src->GetWidth());
+ Math::ClampLength(src_y, src_height, 0, src->GetHeight());
- sourcePic = newPic;
+ // TODO: possibly optimize by not making a stretched intermediate bitmap
+ // if simplier blit/draw_sprite could be called (no translucency with alpha channel).
+ bool needToFreeBitmap = false;
+ if (dst_width != src->GetWidth() || dst_height != src->GetHeight() ||
+ src_width != src->GetWidth() || src_height != src->GetHeight()) {
+ // Resize and/or partial copy specified
+ Bitmap *newPic = BitmapHelper::CreateBitmap(dst_width, dst_height, src->GetColorDepth());
+ newPic->StretchBlt(src,
+ RectWH(src_x, src_y, src_width, src_height),
+ RectWH(0, 0, dst_width, dst_height));
+
+ src = newPic;
needToFreeBitmap = true;
update_polled_stuff_if_runtime();
}
- Bitmap *ds = sds->StartDrawing();
- sds->PointToGameResolution(&xx, &yy);
+ ds = sds->StartDrawing();
+ sds->PointToGameResolution(&dst_x, &dst_y);
- if (sourcePic->GetColorDepth() != ds->GetColorDepth()) {
+ if (src->GetColorDepth() != ds->GetColorDepth()) {
debug_script_warn("RawDrawImage: Sprite %d colour depth %d-bit not same as background depth %d-bit", slot, _GP(spriteset)[slot]->GetColorDepth(), ds->GetColorDepth());
}
- draw_sprite_support_alpha(ds, sds->hasAlphaChannel != 0, xx, yy, sourcePic, (_GP(game).SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0,
- kBlendMode_Alpha, GfxDef::Trans100ToAlpha255(trans));
+ draw_sprite_support_alpha(ds, sds->hasAlphaChannel != 0, dst_x, dst_y, src, (_GP(game).SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0,
+ kBlendMode_Alpha, GfxDef::Trans100ToAlpha255(trans));
sds->FinishedDrawing();
if (needToFreeBitmap)
- delete sourcePic;
+ delete src;
}
+void DrawingSurface_DrawImage(ScriptDrawingSurface *sds, int xx, int yy, int slot, int trans, int width, int height) {
+ DrawingSurface_DrawImageEx(sds, xx, yy, slot, trans, width, height, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE);
+}
void DrawingSurface_SetDrawingColor(ScriptDrawingSurface *sds, int newColour) {
sds->currentColourScript = newColour;
@@ -404,10 +439,17 @@ RuntimeScriptValue Sc_DrawingSurface_DrawCircle(void *self, const RuntimeScriptV
}
// void (ScriptDrawingSurface* sds, int xx, int yy, int slot, int trans, int width, int height)
-RuntimeScriptValue Sc_DrawingSurface_DrawImage(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+RuntimeScriptValue Sc_DrawingSurface_DrawImage_6(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_VOID_PINT6(ScriptDrawingSurface, DrawingSurface_DrawImage);
}
+RuntimeScriptValue Sc_DrawingSurface_DrawImage(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+ ASSERT_OBJ_PARAM_COUNT(METHOD, 10);
+ DrawingSurface_DrawImageEx((ScriptDrawingSurface *)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue,
+ params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue);
+ return RuntimeScriptValue((int32_t)0);
+}
+
// void (ScriptDrawingSurface *sds, int fromx, int fromy, int tox, int toy, int thickness)
RuntimeScriptValue Sc_DrawingSurface_DrawLine(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_VOID_PINT5(ScriptDrawingSurface, DrawingSurface_DrawLine);
@@ -504,7 +546,8 @@ void RegisterDrawingSurfaceAPI(ScriptAPIVersion base_api, ScriptAPIVersion compa
ccAddExternalObjectFunction("DrawingSurface::Clear^1", Sc_DrawingSurface_Clear);
ccAddExternalObjectFunction("DrawingSurface::CreateCopy^0", Sc_DrawingSurface_CreateCopy);
ccAddExternalObjectFunction("DrawingSurface::DrawCircle^3", Sc_DrawingSurface_DrawCircle);
- ccAddExternalObjectFunction("DrawingSurface::DrawImage^6", Sc_DrawingSurface_DrawImage);
+ ccAddExternalObjectFunction("DrawingSurface::DrawImage^6", Sc_DrawingSurface_DrawImage_6);
+ ccAddExternalObjectFunction("DrawingSurface::DrawImage^10", Sc_DrawingSurface_DrawImage);
ccAddExternalObjectFunction("DrawingSurface::DrawLine^5", Sc_DrawingSurface_DrawLine);
ccAddExternalObjectFunction("DrawingSurface::DrawMessageWrapped^5", Sc_DrawingSurface_DrawMessageWrapped);
ccAddExternalObjectFunction("DrawingSurface::DrawPixel^2", Sc_DrawingSurface_DrawPixel);
Commit: 37c51eeac51dc2c9ecd8bc849ab16efb9be1dcb5
https://github.com/scummvm/scummvm/commit/37c51eeac51dc2c9ecd8bc849ab16efb9be1dcb5
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:36-07:00
Commit Message:
AGS: Support extended params for DrawSurface
>From upstream 67810b264d60f55571b1fb604ee5de833a08bfde
Changed paths:
engines/ags/engine/ac/drawing_surface.cpp
diff --git a/engines/ags/engine/ac/drawing_surface.cpp b/engines/ags/engine/ac/drawing_surface.cpp
index b2ec3effe0..33ab8ff735 100644
--- a/engines/ags/engine/ac/drawing_surface.cpp
+++ b/engines/ags/engine/ac/drawing_surface.cpp
@@ -114,46 +114,21 @@ ScriptDrawingSurface *DrawingSurface_CreateCopy(ScriptDrawingSurface *sds) {
return nullptr;
}
-void DrawingSurface_DrawSurface(ScriptDrawingSurface *target, ScriptDrawingSurface *source, int translev) {
- if ((translev < 0) || (translev > 99))
- quit("!DrawingSurface.DrawSurface: invalid parameter (transparency must be 0-99)");
-
- Bitmap *ds = target->StartDrawing();
- Bitmap *surfaceToDraw = source->GetBitmapSurface();
-
- if (surfaceToDraw == target->GetBitmapSurface())
- quit("!DrawingSurface.DrawSurface: cannot draw surface onto itself");
-
- if (translev == 0) {
- // just draw it over the top, no transparency
- ds->Blit(surfaceToDraw, 0, 0, 0, 0, surfaceToDraw->GetWidth(), surfaceToDraw->GetHeight());
- target->FinishedDrawing();
- return;
- }
-
- if (surfaceToDraw->GetColorDepth() <= 8)
- quit("!DrawingSurface.DrawSurface: 256-colour surfaces cannot be drawn transparently");
-
- // Draw it transparently
- GfxUtil::DrawSpriteWithTransparency(ds, surfaceToDraw, 0, 0,
- GfxDef::Trans100ToAlpha255(translev));
- target->FinishedDrawing();
-}
-
-void DrawingSurface_DrawImageEx(ScriptDrawingSurface *sds, int dst_x, int dst_y, int slot, int trans, int dst_width, int dst_height,
- int src_x, int src_y, int src_width, int src_height) {
- if ((slot < 0) || (_GP(spriteset)[slot] == nullptr))
- quit("!DrawingSurface.DrawImage: invalid sprite slot number specified");
+void DrawingSurface_DrawImageImpl(ScriptDrawingSurface *sds, Bitmap *src,
+ int dst_x, int dst_y, int trans, int dst_width, int dst_height,
+ int src_x, int src_y, int src_width, int src_height, int sprite_id, bool src_has_alpha) {
+ Bitmap *ds = sds->GetBitmapSurface();
+ if (src == ds)
+ quit("!DrawingSurface.DrawImage: cannot draw onto itself");
if ((trans < 0) || (trans > 100))
quit("!DrawingSurface.DrawImage: invalid transparency setting");
+
if (trans == 100)
return; // fully transparent
if (dst_width < 1 || dst_height < 1 || src_width < 1 || src_height < 1)
return; // invalid src or dest rectangles
- // Setup uninitialized arguments; convert coordinates for legacy script mode
- Bitmap *ds = sds->GetBitmapSurface();
- Bitmap *src = _GP(spriteset)[slot];
+ // Setup uninitialized arguments; convert coordinates for legacy script mode
if (dst_width == SCR_NO_VALUE) {
dst_width = src->GetWidth();
} else {
@@ -186,7 +161,7 @@ void DrawingSurface_DrawImageEx(ScriptDrawingSurface *sds, int dst_x, int dst_y,
if (dst_x >= ds->GetWidth() || dst_x + dst_width <= 0 || dst_y >= ds->GetHeight() || dst_y + dst_height <= 0 ||
src_x >= src->GetWidth() || src_x + src_width <= 0 || src_y >= src->GetHeight() || src_y + src_height <= 0)
return; // source or destination rects lie completely off surface
- // Clamp the source rect to the valid limits to prevent exceptions (ignore dest, bitmap drawing deals with that)
+ // Clamp the source rect to the valid limits to prevent exceptions (ignore dest, bitmap drawing deals with that)
Math::ClampLength(src_x, src_width, 0, src->GetWidth());
Math::ClampLength(src_y, src_height, 0, src->GetHeight());
@@ -210,10 +185,13 @@ void DrawingSurface_DrawImageEx(ScriptDrawingSurface *sds, int dst_x, int dst_y,
sds->PointToGameResolution(&dst_x, &dst_y);
if (src->GetColorDepth() != ds->GetColorDepth()) {
- debug_script_warn("RawDrawImage: Sprite %d colour depth %d-bit not same as background depth %d-bit", slot, _GP(spriteset)[slot]->GetColorDepth(), ds->GetColorDepth());
+ if (sprite_id >= 0)
+ debug_script_warn("DrawImage: Sprite %d colour depth %d-bit not same as background depth %d-bit", sprite_id, src->GetColorDepth(), ds->GetColorDepth());
+ else
+ debug_script_warn("DrawImage: Source image colour depth %d-bit not same as background depth %d-bit", src->GetColorDepth(), ds->GetColorDepth());
}
- draw_sprite_support_alpha(ds, sds->hasAlphaChannel != 0, dst_x, dst_y, src, (_GP(game).SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0,
+ draw_sprite_support_alpha(ds, sds->hasAlphaChannel != 0, dst_x, dst_y, src, src_has_alpha,
kBlendMode_Alpha, GfxDef::Trans100ToAlpha255(trans));
sds->FinishedDrawing();
@@ -222,10 +200,31 @@ void DrawingSurface_DrawImageEx(ScriptDrawingSurface *sds, int dst_x, int dst_y,
delete src;
}
+void DrawingSurface_DrawImageEx(ScriptDrawingSurface *sds,
+ int dst_x, int dst_y, int slot, int trans,
+ int dst_width, int dst_height,
+ int src_x, int src_y, int src_width, int src_height) {
+ if ((slot < 0) || (_GP(spriteset)[slot] == nullptr))
+ quit("!DrawingSurface.DrawImage: invalid sprite slot number specified");
+ DrawingSurface_DrawImageImpl(sds, _GP(spriteset)[slot], dst_x, dst_y, trans, dst_width, dst_height,
+ src_x, src_y, src_width, src_height, slot, (_GP(game).SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0);
+}
+
void DrawingSurface_DrawImage(ScriptDrawingSurface *sds, int xx, int yy, int slot, int trans, int width, int height) {
DrawingSurface_DrawImageEx(sds, xx, yy, slot, trans, width, height, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE);
}
+void DrawingSurface_DrawSurfaceEx(ScriptDrawingSurface *target, ScriptDrawingSurface *source, int trans,
+ int dst_x, int dst_y, int dst_width, int dst_height,
+ int src_x, int src_y, int src_width, int src_height) {
+ DrawingSurface_DrawImageImpl(target, source->GetBitmapSurface(), dst_x, dst_y, trans, dst_width, dst_height,
+ src_x, src_y, src_width, src_height, -1, source->hasAlphaChannel);
+}
+
+void DrawingSurface_DrawSurface(ScriptDrawingSurface *target, ScriptDrawingSurface *source, int trans) {
+ DrawingSurface_DrawSurfaceEx(target, source, trans, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE);
+}
+
void DrawingSurface_SetDrawingColor(ScriptDrawingSurface *sds, int newColour) {
sds->currentColourScript = newColour;
// StartDrawing to set up ds to set the colour at the appropriate
@@ -487,10 +486,18 @@ RuntimeScriptValue Sc_DrawingSurface_DrawStringWrapped(void *self, const Runtime
}
// void (ScriptDrawingSurface* target, ScriptDrawingSurface* source, int translev)
-RuntimeScriptValue Sc_DrawingSurface_DrawSurface(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+RuntimeScriptValue Sc_DrawingSurface_DrawSurface_2(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_VOID_POBJ_PINT(ScriptDrawingSurface, DrawingSurface_DrawSurface, ScriptDrawingSurface);
}
+RuntimeScriptValue Sc_DrawingSurface_DrawSurface(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+ ASSERT_OBJ_PARAM_COUNT(METHOD, 10);
+ DrawingSurface_DrawSurfaceEx((ScriptDrawingSurface *)self, (ScriptDrawingSurface *)params[0].Ptr,
+ params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue,
+ params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue);
+ return RuntimeScriptValue((int32_t)0);
+}
+
// void (ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2, int x3, int y3)
RuntimeScriptValue Sc_DrawingSurface_DrawTriangle(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_VOID_PINT6(ScriptDrawingSurface, DrawingSurface_DrawTriangle);
@@ -557,7 +564,8 @@ void RegisterDrawingSurfaceAPI(ScriptAPIVersion base_api, ScriptAPIVersion compa
ccAddExternalObjectFunction("DrawingSurface::DrawStringWrapped^6", Sc_DrawingSurface_DrawStringWrapped_Old);
else
ccAddExternalObjectFunction("DrawingSurface::DrawStringWrapped^6", Sc_DrawingSurface_DrawStringWrapped);
- ccAddExternalObjectFunction("DrawingSurface::DrawSurface^2", Sc_DrawingSurface_DrawSurface);
+ ccAddExternalObjectFunction("DrawingSurface::DrawSurface^2", Sc_DrawingSurface_DrawSurface_2);
+ ccAddExternalObjectFunction("DrawingSurface::DrawSurface^10", Sc_DrawingSurface_DrawSurface);
ccAddExternalObjectFunction("DrawingSurface::DrawTriangle^6", Sc_DrawingSurface_DrawTriangle);
ccAddExternalObjectFunction("DrawingSurface::GetPixel^2", Sc_DrawingSurface_GetPixel);
ccAddExternalObjectFunction("DrawingSurface::Release^0", Sc_DrawingSurface_Release);
Commit: 9f78c2f22cf55ac4c44143e5f1eb967c288e1189
https://github.com/scummvm/scummvm/commit/9f78c2f22cf55ac4c44143e5f1eb967c288e1189
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:36-07:00
Commit Message:
AGS: Added WaitMouse() to complement existing Wait funcs
>From upstream b623980549cc7355c5ca3db9adf4ef29463d65d6
Changed paths:
engines/ags/engine/ac/global_api.cpp
engines/ags/engine/ac/global_game.cpp
engines/ags/engine/ac/global_game.h
diff --git a/engines/ags/engine/ac/global_api.cpp b/engines/ags/engine/ac/global_api.cpp
index 5cc1c35994..dc6f1f8d3c 100644
--- a/engines/ags/engine/ac/global_api.cpp
+++ b/engines/ags/engine/ac/global_api.cpp
@@ -1862,6 +1862,10 @@ RuntimeScriptValue Sc_WaitKey(const RuntimeScriptValue *params, int32_t param_co
API_SCALL_INT_PINT(WaitKey);
}
+RuntimeScriptValue Sc_WaitMouse(const RuntimeScriptValue *params, int32_t param_count) {
+ API_SCALL_INT_PINT(WaitMouse);
+}
+
// int (int nloops)
RuntimeScriptValue Sc_WaitMouseKey(const RuntimeScriptValue *params, int32_t param_count) {
API_SCALL_INT_PINT(WaitMouseKey);
@@ -2235,6 +2239,7 @@ void RegisterGlobalAPI() {
ccAddExternalStaticFunction("UpdatePalette", Sc_UpdatePalette);
ccAddExternalStaticFunction("Wait", Sc_scrWait);
ccAddExternalStaticFunction("WaitKey", Sc_WaitKey);
+ ccAddExternalStaticFunction("WaitMouse", Sc_WaitMouse);
ccAddExternalStaticFunction("WaitMouseKey", Sc_WaitMouseKey);
}
diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp
index 6dea34994e..27ebd78253 100644
--- a/engines/ags/engine/ac/global_game.cpp
+++ b/engines/ags/engine/ac/global_game.cpp
@@ -792,6 +792,10 @@ int WaitKey(int nloops) {
return WaitImpl(SKIP_KEYPRESS | SKIP_AUTOTIMER, nloops);
}
+int WaitMouse(int nloops) {
+ return WaitImpl(SKIP_MOUSECLICK | SKIP_AUTOTIMER, nloops);
+}
+
int WaitMouseKey(int nloops) {
return WaitImpl(SKIP_KEYPRESS | SKIP_MOUSECLICK | SKIP_AUTOTIMER, nloops);
}
diff --git a/engines/ags/engine/ac/global_game.h b/engines/ags/engine/ac/global_game.h
index 35902055cc..a250ab8dbd 100644
--- a/engines/ags/engine/ac/global_game.h
+++ b/engines/ags/engine/ac/global_game.h
@@ -106,6 +106,7 @@ int GetGraphicalVariable(const char *varName);
void SetGraphicalVariable(const char *varName, int p_value);
void scrWait(int nloops);
int WaitKey(int nloops);
+int WaitMouse(int nloops);
int WaitMouseKey(int nloops);
} // namespace AGS3
Commit: b4997729cd36ccc4eaba7f1ecb7e54922acf4b57
https://github.com/scummvm/scummvm/commit/b4997729cd36ccc4eaba7f1ecb7e54922acf4b57
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:36-07:00
Commit Message:
AGS: Wait functions return the actual reason they were skipped
>From upstream 5a9a32348659f421115a951155405d431f8f3234
Changed paths:
engines/ags/engine/ac/game_state.h
engines/ags/engine/ac/global_game.cpp
engines/ags/engine/main/game_run.cpp
diff --git a/engines/ags/engine/ac/game_state.h b/engines/ags/engine/ac/game_state.h
index 1b1bee1db1..babff172be 100644
--- a/engines/ags/engine/ac/game_state.h
+++ b/engines/ags/engine/ac/game_state.h
@@ -157,6 +157,8 @@ struct GameState {
int bg_frame = 0, bg_anim_delay = 0; // for animating backgrounds
int music_vol_was = 0; // before the volume drop
short wait_counter = 0;
+ char wait_skipped_by = 0; // tells how last wait was skipped [not serialized]
+ int wait_skipped_by_data = 0; // extended data telling how last wait was skipped [not serialized]
short mboundx1 = 0, mboundx2 = 0, mboundy1 = 0, mboundy2 = 0;
int fade_effect = 0;
int bg_frame_locked = 0;
diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp
index 27ebd78253..51b685d7a5 100644
--- a/engines/ags/engine/ac/global_game.cpp
+++ b/engines/ags/engine/ac/global_game.cpp
@@ -775,13 +775,22 @@ int WaitImpl(int skip_type, int nloops) {
quit("!Wait: must wait at least 1 loop");
_GP(play).wait_counter = nloops;
+ _GP(play).wait_skipped_by = SKIP_AUTOTIMER; // we set timer flag by default to simplify that case
+ _GP(play).wait_skipped_by_data = 0;
_GP(play).key_skip_wait = skip_type;
GameLoopUntilValueIsZeroOrLess(&_GP(play).wait_counter);
- if (_GP(play).wait_counter < 0)
- return 1;
- return 0;
+ if (_GP(game).options[OPT_BASESCRIPTAPI] < kScriptAPI_v360) {
+ // < 3.6.0 return 1 is skipped by user input, otherwise 0
+ return (_GP(play).wait_skipped_by & (SKIP_KEYPRESS | SKIP_MOUSECLICK) != 0) ? 1 : 0;
+ }
+ // >= 3.6.0 return positive keycode, negative mouse button code, or 0 as time-out
+ switch (_GP(play).wait_skipped_by) {
+ case SKIP_KEYPRESS: return _GP(play).wait_skipped_by_data;
+ case SKIP_MOUSECLICK: return -(_GP(play).wait_skipped_by_data + 1); // convert to 1-based code and negate
+ default: return 0;
+ }
}
void scrWait(int nloops) {
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index 02ef458ed5..b74f345761 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -209,9 +209,11 @@ static void check_mouse_controls() {
check_skip_cutscene_mclick(mbut);
if (_GP(play).fast_forward || _GP(play).IsIgnoringInput()) { /* do nothing if skipping cutscene or input disabled */
- } else if ((_GP(play).wait_counter > 0) && (_GP(play).key_skip_wait & SKIP_MOUSECLICK) != 0)
- _GP(play).wait_counter = -1;
- else if (_G(is_text_overlay) > 0) {
+ } else if ((_GP(play).wait_counter > 0) && (_GP(play).key_skip_wait & SKIP_MOUSECLICK) != 0) {
+ _GP(play).wait_counter = 0;
+ _GP(play).wait_skipped_by = SKIP_MOUSECLICK;
+ _GP(play).wait_skipped_by_data = mbut;
+ } else if (_G(is_text_overlay) > 0) {
if (_GP(play).cant_skip_speech & SKIP_MOUSECLICK)
remove_screen_overlay(OVER_TEXTMSG);
} else if (!IsInterfaceEnabled()); // blocking cutscene, ignore mouse
Commit: 0b4b055d6f243e5c05d776627d5861cad747bf51
https://github.com/scummvm/scummvm/commit/0b4b055d6f243e5c05d776627d5861cad747bf51
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:37-07:00
Commit Message:
AGS: Wait functions may have infinite timeout with <0 time arg
>From upstream 53c8b50559f6e8241ba7dbedbe1a8ff860522590
Changed paths:
engines/ags/engine/ac/global_game.cpp
engines/ags/engine/main/game_run.cpp
diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp
index 51b685d7a5..5fee4426ff 100644
--- a/engines/ags/engine/ac/global_game.cpp
+++ b/engines/ags/engine/ac/global_game.cpp
@@ -771,19 +771,16 @@ void SetGraphicalVariable(const char *varName, int p_value) {
}
int WaitImpl(int skip_type, int nloops) {
- if ((nloops < 1) && (_G(loaded_game_file_version) >= kGameVersion_262)) // 2.62+
- quit("!Wait: must wait at least 1 loop");
-
_GP(play).wait_counter = nloops;
_GP(play).wait_skipped_by = SKIP_AUTOTIMER; // we set timer flag by default to simplify that case
_GP(play).wait_skipped_by_data = 0;
_GP(play).key_skip_wait = skip_type;
- GameLoopUntilValueIsZeroOrLess(&_GP(play).wait_counter);
+ GameLoopUntilValueIsZero(&_GP(play).wait_counter);
if (_GP(game).options[OPT_BASESCRIPTAPI] < kScriptAPI_v360) {
// < 3.6.0 return 1 is skipped by user input, otherwise 0
- return (_GP(play).wait_skipped_by & (SKIP_KEYPRESS | SKIP_MOUSECLICK) != 0) ? 1 : 0;
+ return (_GP(play).wait_skipped_by & (SKIP_KEYPRESS | SKIP_MOUSECLICK)) != 0 ? 1 : 0;
}
// >= 3.6.0 return positive keycode, negative mouse button code, or 0 as time-out
switch (_GP(play).wait_skipped_by) {
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index b74f345761..b435e7f995 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() {
check_skip_cutscene_mclick(mbut);
if (_GP(play).fast_forward || _GP(play).IsIgnoringInput()) { /* do nothing if skipping cutscene or input disabled */
- } else if ((_GP(play).wait_counter > 0) && (_GP(play).key_skip_wait & SKIP_MOUSECLICK) != 0) {
+ } else if ((_GP(play).wait_counter != 0) && (_GP(play).key_skip_wait & SKIP_MOUSECLICK) != 0) {
_GP(play).wait_counter = 0;
_GP(play).wait_skipped_by = SKIP_MOUSECLICK;
_GP(play).wait_skipped_by_data = mbut;
@@ -445,7 +445,7 @@ static void check_keyboard_controls() {
return;
}
- if ((_GP(play).wait_counter > 0) && (_GP(play).key_skip_wait & SKIP_KEYPRESS) != 0) {
+ if ((_GP(play).wait_counter != 0) && (_GP(play).key_skip_wait & SKIP_KEYPRESS) != 0) {
_GP(play).wait_counter = -1;
debug_script_log("Keypress code %d ignored - in Wait", kgn);
return;
Commit: 529362a2d70a86cd21e6636e811f8e815f550bb4
https://github.com/scummvm/scummvm/commit/529362a2d70a86cd21e6636e811f8e815f550bb4
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:37-07:00
Commit Message:
AGS: implemented SkipWait()
>From upstream 3b3aed5b4e33d1791d8eac922c9d530e5796d984
Changed paths:
engines/ags/engine/ac/global_api.cpp
engines/ags/engine/ac/global_game.cpp
engines/ags/engine/ac/global_game.h
diff --git a/engines/ags/engine/ac/global_api.cpp b/engines/ags/engine/ac/global_api.cpp
index dc6f1f8d3c..81437c619e 100644
--- a/engines/ags/engine/ac/global_api.cpp
+++ b/engines/ags/engine/ac/global_api.cpp
@@ -1871,6 +1871,10 @@ RuntimeScriptValue Sc_WaitMouseKey(const RuntimeScriptValue *params, int32_t par
API_SCALL_INT_PINT(WaitMouseKey);
}
+RuntimeScriptValue Sc_SkipWait(const RuntimeScriptValue *params, int32_t param_count) {
+ API_SCALL_VOID(SkipWait);
+}
+
void RegisterGlobalAPI() {
ccAddExternalStaticFunction("AbortGame", Sc_sc_AbortGame);
ccAddExternalStaticFunction("AddInventory", Sc_add_inventory);
@@ -2241,6 +2245,7 @@ void RegisterGlobalAPI() {
ccAddExternalStaticFunction("WaitKey", Sc_WaitKey);
ccAddExternalStaticFunction("WaitMouse", Sc_WaitMouse);
ccAddExternalStaticFunction("WaitMouseKey", Sc_WaitMouseKey);
+ ccAddExternalStaticFunction("SkipWait", Sc_SkipWait);
}
} // namespace AGS3
diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp
index 5fee4426ff..4c9bc30f6e 100644
--- a/engines/ags/engine/ac/global_game.cpp
+++ b/engines/ags/engine/ac/global_game.cpp
@@ -806,4 +806,8 @@ int WaitMouseKey(int nloops) {
return WaitImpl(SKIP_KEYPRESS | SKIP_MOUSECLICK | SKIP_AUTOTIMER, nloops);
}
+void SkipWait() {
+ _GP(play).wait_counter = 0;
+}
+
} // namespace AGS3
diff --git a/engines/ags/engine/ac/global_game.h b/engines/ags/engine/ac/global_game.h
index a250ab8dbd..6cf7246e87 100644
--- a/engines/ags/engine/ac/global_game.h
+++ b/engines/ags/engine/ac/global_game.h
@@ -108,6 +108,7 @@ void scrWait(int nloops);
int WaitKey(int nloops);
int WaitMouse(int nloops);
int WaitMouseKey(int nloops);
+void SkipWait();
} // namespace AGS3
Commit: 9612b5cb35d7f852e1cde03e1f5eb1fe9a1f776f
https://github.com/scummvm/scummvm/commit/9612b5cb35d7f852e1cde03e1f5eb1fe9a1f776f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:37-07:00
Commit Message:
AGS: distinct overlay types of speech and messagebox
>From upstream d7c091890d2cde07776cca4ebbed7352d379612d
Changed paths:
engines/ags/engine/ac/character.cpp
engines/ags/engine/ac/display.cpp
engines/ags/engine/ac/display.h
engines/ags/engine/ac/draw.cpp
engines/ags/engine/ac/game.cpp
engines/ags/engine/ac/game_state.h
engines/ags/engine/ac/gui.cpp
engines/ags/engine/ac/overlay.cpp
engines/ags/engine/ac/runtime_defines.h
engines/ags/engine/game/savegame.cpp
engines/ags/engine/main/engine.cpp
engines/ags/engine/main/game_run.cpp
engines/ags/engine/main/update.cpp
engines/ags/globals.h
diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp
index e896818f0c..da82cf95b6 100644
--- a/engines/ags/engine/ac/character.cpp
+++ b/engines/ags/engine/ac/character.cpp
@@ -2253,7 +2253,7 @@ void _displayspeech(const char *texx, int aschar, int xx, int yy, int widd, int
if ((speakingChar->view < 0) || (speakingChar->view >= _GP(game).numviews))
quit("!DisplaySpeech: character has invalid view");
- if (_G(is_text_overlay) > 0) {
+ if (_GP(play).text_overlay_on > 0) {
debug_script_warn("DisplaySpeech: speech was already displayed (nested DisplaySpeech, perhaps room script and global script conflict?)");
return;
}
diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp
index 59671a472c..0a1b94be89 100644
--- a/engines/ags/engine/ac/display.cpp
+++ b/engines/ags/engine/ac/display.cpp
@@ -173,7 +173,7 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int
int extraHeight = paddingDoubledScaled;
color_t text_color = MakeColor(15);
if (disp_type < DISPLAYTEXT_NORMALOVERLAY)
- remove_screen_overlay(OVER_TEXTMSG); // remove any previous blocking texts
+ remove_screen_overlay(_GP(play).text_overlay_on); // remove any previous blocking texts
const int bmp_width = std::max(2, wii);
const int bmp_height = std::max(2, disp.fulltxtheight + extraHeight);
@@ -246,9 +246,13 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int
wouttext_aligned(text_window_ds, xoffs, yoffs + ee * disp.linespacing, oriwid, usingfont, text_color, _GP(Lines)[ee].GetCStr(), _GP(play).text_align);
}
- int ovrtype = OVER_TEXTMSG;
- if (disp_type == DISPLAYTEXT_NORMALOVERLAY) ovrtype = OVER_CUSTOM;
- else if (disp_type >= OVER_CUSTOM) ovrtype = disp_type;
+ int ovrtype;
+ switch (disp_type) {
+ case DISPLAYTEXT_SPEECH: ovrtype = OVER_TEXTSPEECH; break;
+ case DISPLAYTEXT_MESSAGEBOX: ovrtype = OVER_TEXTMSG; break;
+ case DISPLAYTEXT_NORMALOVERLAY: ovrtype = OVER_CUSTOM; break;
+ default: ovrtype = disp_type; break; // must be precreated overlay id
+ }
int nse = add_screen_overlay(xx, yy, ovrtype, text_window_ds, adjustedXX - xx, adjustedYY - yy, alphaChannel);
// we should not delete text_window_ds here, because it is now owned by Overlay
@@ -329,6 +333,7 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int
remove_screen_overlay(OVER_TEXTMSG);
invalidate_screen();
} else {
+ /* DISPLAYTEXT_SPEECH */
// if the speech does not time out, but we are skipping a cutscene,
// allow it to time out
if ((_GP(play).messagetime < 0) && (_GP(play).fast_forward))
diff --git a/engines/ags/engine/ac/display.h b/engines/ags/engine/ac/display.h
index 5928dff6f9..aa7395508d 100644
--- a/engines/ags/engine/ac/display.h
+++ b/engines/ags/engine/ac/display.h
@@ -30,8 +30,11 @@ namespace AGS3 {
using AGS::Shared::GUIMain;
// options for 'disp_type' parameter
+// blocking speech
#define DISPLAYTEXT_SPEECH 0
+// super-blocking message box
#define DISPLAYTEXT_MESSAGEBOX 1
+// regular non-blocking overlay
#define DISPLAYTEXT_NORMALOVERLAY 2
// also accepts explicit overlay ID >= OVER_CUSTOM
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 6fb675d8aa..1a76213273 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -2099,7 +2099,7 @@ void construct_game_scene(bool full_redraw) {
_GP(play).UpdateRoomCameras();
// Stage: room viewports
- if (_GP(play).screen_is_faded_out == 0 && _G(is_complete_overlay) == 0) {
+ if (_GP(play).screen_is_faded_out == 0 && _GP(play).complete_overlay_on == 0) {
if (_G(displayed_room) >= 0) {
construct_room_view();
} else if (!_G(gfxDriver)->RequiresFullRedrawEachFrame()) {
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index 07bdaa31bb..9546948a0d 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -1093,9 +1093,8 @@ void start_skipping_cutscene() {
remove_popup_interface(_G(ifacepopped));
// if a text message is currently displayed, remove it
- if (_G(is_text_overlay) > 0)
- remove_screen_overlay(OVER_TEXTMSG);
-
+ if (_GP(play).text_overlay_on > 0)
+ remove_screen_overlay(_GP(play).text_overlay_on);
}
bool check_skip_cutscene_keypress(int kgn) {
diff --git a/engines/ags/engine/ac/game_state.h b/engines/ags/engine/ac/game_state.h
index babff172be..50d77cb66d 100644
--- a/engines/ags/engine/ac/game_state.h
+++ b/engines/ags/engine/ac/game_state.h
@@ -246,6 +246,13 @@ struct GameState {
// Tells whether character speech stays on screen not animated for additional time
bool speech_in_post_state = false;
+ // Special overlays
+ //
+ // Is there a QFG4-style dialog overlay on screen (contains overlay ID)
+ int complete_overlay_on = 0;
+ // Is there a blocking text overlay on screen (contains overlay ID)
+ int text_overlay_on = 0;
+
int shake_screen_yoff = 0; // y offset of the shaking screen
diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp
index 4c55450547..7df7200c55 100644
--- a/engines/ags/engine/ac/gui.cpp
+++ b/engines/ags/engine/ac/gui.cpp
@@ -20,7 +20,6 @@
*
*/
-//include <cstdio>
#include "ags/engine/ac/gui.h"
#include "ags/shared/ac/common.h"
#include "ags/engine/ac/draw.h"
@@ -584,8 +583,7 @@ int gui_on_mouse_move() {
if (_GP(guis)[guin].IsInteractableAt(_G(mousex), _G(mousey))) mouse_over_gui = guin;
if (_GP(guis)[guin].PopupStyle != kGUIPopupMouseY) continue;
- if (_G(is_complete_overlay) > 0) break; // interfaces disabled
- // if (_GP(play).disabled_user_interface>0) break;
+ if (_GP(play).complete_overlay_on > 0) break; // interfaces disabled // if (_GP(play).disabled_user_interface>0) break;
if (_G(ifacepopped) == guin) continue;
if (!_GP(guis)[guin].IsVisible()) continue;
// Don't allow it to be popped up while skipping cutscene
diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp
index b3cccac2e9..f7d1f8cc81 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -160,8 +160,8 @@ void dispose_overlay(ScreenOverlay &over) {
void remove_screen_overlay_index(int over_idx) {
ScreenOverlay &over = _G(screenover)[over_idx];
dispose_overlay(over);
- if (over.type == OVER_COMPLETE) _G(is_complete_overlay)--;
- if (over.type == OVER_TEXTMSG) _G(is_text_overlay)--;
+ if (over.type == _GP(play).complete_overlay_on) _GP(play).complete_overlay_on = 0;
+ if (over.type == _GP(play).text_overlay_on) _GP(play).text_overlay_on = 0;
_G(numscreenover)--;
for (int i = over_idx; i < _G(numscreenover); ++i)
_G(screenover)[i] = _G(screenover)[i + 1];
@@ -192,8 +192,8 @@ int add_screen_overlay(int x, int y, int type, Bitmap *piccy, bool alphaChannel)
}
int add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel) {
- if (type == OVER_COMPLETE) _G(is_complete_overlay)++;
- if (type == OVER_TEXTMSG) _G(is_text_overlay)++;
+ if (type == OVER_COMPLETE) _GP(play).complete_overlay_on = type;
+ if (type == OVER_TEXTMSG || type == OVER_TEXTSPEECH) _GP(play).text_overlay_on = type;
if (type == OVER_CUSTOM) {
// find an unused custom ID; TODO: find a better approach!
for (int id = OVER_CUSTOM + 1; id < OVER_CUSTOM + 100; ++id) {
diff --git a/engines/ags/engine/ac/runtime_defines.h b/engines/ags/engine/ac/runtime_defines.h
index ff623cf760..cb29b9ba5d 100644
--- a/engines/ags/engine/ac/runtime_defines.h
+++ b/engines/ags/engine/ac/runtime_defines.h
@@ -112,6 +112,7 @@ const int LegacyRoomVolumeFactor = 30;
#define OVER_TEXTMSG 1
#define OVER_COMPLETE 2
#define OVER_PICTURE 3
+#define OVER_TEXTSPEECH 4
#define OVER_CUSTOM 100
#define OVR_AUTOPLACE 30000
#define FOR_ANIMATION 1
diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp
index 3875852c1c..83e4a0e132 100644
--- a/engines/ags/engine/game/savegame.cpp
+++ b/engines/ags/engine/game/savegame.cpp
@@ -332,8 +332,8 @@ void DoBeforeRestore(PreservedParams &pp) {
delete _G(raw_saved_screen);
_G(raw_saved_screen) = nullptr;
remove_screen_overlay(-1);
- _G(is_complete_overlay) = 0;
- _G(is_text_overlay) = 0;
+ _GP(play).complete_overlay_on = 0;
+ _GP(play).text_overlay_on = 0;
// cleanup dynamic sprites
// NOTE: sprite 0 is a special constant sprite that cannot be dynamic
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index ccb98eef87..b381178381 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -807,6 +807,8 @@ void engine_init_game_settings() {
_GP(play).speech_has_voice = false;
_GP(play).speech_voice_blocking = false;
_GP(play).speech_in_post_state = false;
+ _GP(play).complete_overlay_on = 0;
+ _GP(play).text_overlay_on = 0;
_GP(play).narrator_speech = _GP(game).playercharacter;
_GP(play).crossfading_out_channel = 0;
_GP(play).speech_textwindow_gui = _GP(game).options[OPT_TWCUSTOM];
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index b435e7f995..e275862a03 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -25,8 +25,6 @@
//
#include "ags/lib/std/limits.h"
-//include <chrono>
-//include <SDL.h>
#include "ags/shared/ac/common.h"
#include "ags/engine/ac/character_extras.h"
#include "ags/shared/ac/character_info.h"
@@ -213,9 +211,9 @@ static void check_mouse_controls() {
_GP(play).wait_counter = 0;
_GP(play).wait_skipped_by = SKIP_MOUSECLICK;
_GP(play).wait_skipped_by_data = mbut;
- } else if (_G(is_text_overlay) > 0) {
+ } else if (_GP(play).text_overlay_on > 0) {
if (_GP(play).cant_skip_speech & SKIP_MOUSECLICK)
- remove_screen_overlay(OVER_TEXTMSG);
+ remove_screen_overlay(_GP(play).text_overlay_on);
} else if (!IsInterfaceEnabled()); // blocking cutscene, ignore mouse
else if (pl_run_plugin_hooks(AGSE_MOUSECLICK, mbut + 1)) {
// plugin took the click
@@ -383,7 +381,7 @@ bool run_service_key_controls(KeyInput &out_key) {
}
if (((agskey == eAGSKeyCodeCtrlV) && (cur_key_mods & Common::KBD_ALT) != 0)
- && (_GP(play).wait_counter < 1) && (_G(is_text_overlay) == 0) && (_G(restrict_until) == 0)) {
+ && (_GP(play).wait_counter < 1) && (_GP(play).text_overlay_on == 0) && (_G(restrict_until) == 0)) {
// make sure we can't interrupt a Wait()
// and desync the music to cutscene
_GP(play).debug_mode++;
@@ -432,14 +430,14 @@ static void check_keyboard_controls() {
}
// skip speech if desired by Speech.SkipStyle
- if ((_G(is_text_overlay) > 0) && (_GP(play).cant_skip_speech & SKIP_KEYPRESS)) {
+ if ((_GP(play).text_overlay_on > 0) && (_GP(play).cant_skip_speech & SKIP_KEYPRESS)) {
// 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
if ((_GP(play).skip_speech_specific_key > 0) &&
- (kgn != _GP(play).skip_speech_specific_key)) {
+ (kgn != _GP(play).skip_speech_specific_key)) {
} else
- remove_screen_overlay(OVER_TEXTMSG);
+ remove_screen_overlay(_GP(play).text_overlay_on);
}
return;
@@ -835,7 +833,7 @@ static int ShouldStayInWaitMode() {
const int *wkptr = (const int *)_G(user_disabled_data);
if (wkptr[0] < 0) retval = 0;
} else if (_G(restrict_until) == UNTIL_NOOVERLAY) {
- if (_G(is_text_overlay) < 1) retval = 0;
+ if (_GP(play).text_overlay_on == 0) retval = 0;
} else if (_G(restrict_until) == UNTIL_INTIS0) {
const int *wkptr = (const int *)_G(user_disabled_data);
if (wkptr[0] == 0) retval = 0;
diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp
index 2572b2a1a7..a7ae9981fe 100644
--- a/engines/ags/engine/main/update.cpp
+++ b/engines/ags/engine/main/update.cpp
@@ -260,9 +260,9 @@ void update_speech_and_messages() {
if (_GP(play).messagetime < 1) {
if (_GP(play).fast_forward > 0) {
- remove_screen_overlay(OVER_TEXTMSG);
+ remove_screen_overlay(_GP(play).text_overlay_on);
} else if (_GP(play).cant_skip_speech & SKIP_AUTOTIMER) {
- remove_screen_overlay(OVER_TEXTMSG);
+ remove_screen_overlay(_GP(play).text_overlay_on);
_GP(play).SetIgnoreInput(_GP(play).ignore_user_input_after_text_timeout_ms);
}
}
@@ -371,7 +371,7 @@ void update_sierra_speech() {
}
// _G(is_text_overlay) might be 0 if it was only just destroyed this loop
- if ((updatedFrame) && (_G(is_text_overlay) > 0)) {
+ if ((updatedFrame) && (_GP(play).text_overlay_on > 0)) {
if (updatedFrame & 1)
CheckViewFrame(_G(facetalkview), _G(facetalkloop), _G(facetalkframe));
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 60c51933fc..04b6635430 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -1144,7 +1144,7 @@ public:
*/
ScreenOverlay *_screenover;
- int _is_complete_overlay = 0, _is_text_overlay = 0;
+ int _is_complete_overlay = 0;
int _numscreenover = 0;
/**@}*/
Commit: c133e516209f6e0f0edcb1429c9ff18135b5f367
https://github.com/scummvm/scummvm/commit/c133e516209f6e0f0edcb1429c9ff18135b5f367
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:37-07:00
Commit Message:
AGS: Speech.TextOverlay for accessing blocking speech overlay
>From upstream 1affbd4d57686e3080ebdb21a0cd33ee4af04b75
Changed paths:
engines/ags/engine/ac/character.cpp
engines/ags/engine/ac/game_state.h
engines/ags/engine/ac/overlay.cpp
engines/ags/engine/ac/overlay.h
engines/ags/engine/ac/speech.cpp
diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp
index da82cf95b6..5433b8cc70 100644
--- a/engines/ags/engine/ac/character.cpp
+++ b/engines/ags/engine/ac/character.cpp
@@ -708,14 +708,10 @@ ScriptOverlay *Character_SayBackground(CharacterInfo *chaa, const char *texx) {
if (ovri < 0)
quit("!SayBackground internal error: no overlay");
- // Convert the overlay ID to an Overlay object
- ScriptOverlay *scOver = new ScriptOverlay();
- scOver->overlayId = ovltype;
+ ScriptOverlay *scOver = create_scriptobj_for_overlay(_G(screenover)[ovri]);
scOver->borderHeight = 0;
scOver->borderWidth = 0;
scOver->isBackgroundSpeech = 1;
- int handl = ccRegisterManagedObject(scOver, scOver);
- _G(screenover)[ovri].associatedOverlayHandle = handl;
return scOver;
}
diff --git a/engines/ags/engine/ac/game_state.h b/engines/ags/engine/ac/game_state.h
index 50d77cb66d..2ffc72ec46 100644
--- a/engines/ags/engine/ac/game_state.h
+++ b/engines/ags/engine/ac/game_state.h
@@ -53,6 +53,7 @@ struct RestoredData;
using namespace AGS; // FIXME later
struct ScriptViewport;
struct ScriptCamera;
+struct ScriptOverlay;
#define GAME_STATE_RESERVED_INTS 5
@@ -252,6 +253,8 @@ struct GameState {
int complete_overlay_on = 0;
// Is there a blocking text overlay on screen (contains overlay ID)
int text_overlay_on = 0;
+ // Blocking speech overlay managed object, for accessing in scripts
+ ScriptOverlay *speech_text_scover = nullptr;
int shake_screen_yoff = 0; // y offset of the shaking screen
diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp
index f7d1f8cc81..e6466d6e6e 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -145,28 +145,56 @@ ScriptOverlay *Overlay_CreateTextual(int x, int y, int width, int font, int colo
//=============================================================================
-void dispose_overlay(ScreenOverlay &over) {
+// Creates and registers a managed script object for existing overlay object
+ScriptOverlay *create_scriptobj_for_overlay(ScreenOverlay &over) {
+ ScriptOverlay *scover = new ScriptOverlay();
+ scover->overlayId = over.type;
+ int handl = ccRegisterManagedObject(scover, scover);
+ over.associatedOverlayHandle = handl;
+ return scover;
+}
+
+// Creates managed script object for overlay and adds internal engine's reference to it,
+// so that it does not get disposed even if there are no user references in script.
+static ScriptOverlay *create_scriptobj_addref(ScreenOverlay &over) {
+ ScriptOverlay *scover = create_scriptobj_for_overlay(over);
+ ccAddObjectReference(over.associatedOverlayHandle);
+ return scover;
+}
+
+// Invalidates existing script object to let user know that previous overlay is gone,
+// and releases engine's internal reference (script object may exist while there are user refs)
+static void invalidate_and_subref(ScreenOverlay &over, ScriptOverlay *&scover) {
+ scover->overlayId = -1;
+ scover = nullptr;
+ ccReleaseObjectReference(over.associatedOverlayHandle);
+}
+
+// Frees overlay resources and disposes script object if there are no more refs
+static void dispose_overlay(ScreenOverlay &over) {
delete over.pic;
over.pic = nullptr;
if (over.bmp != nullptr)
_G(gfxDriver)->DestroyDDB(over.bmp);
over.bmp = nullptr;
- // if the script didn't actually use the Overlay* return
- // value, dispose of the pointer
- if (over.associatedOverlayHandle)
+ if (over.associatedOverlayHandle) // dispose script object if there are no more refs
ccAttemptDisposeObject(over.associatedOverlayHandle);
}
void remove_screen_overlay_index(int over_idx) {
ScreenOverlay &over = _G(screenover)[over_idx];
+ if (over.type == _GP(play).complete_overlay_on) {
+ _GP(play).complete_overlay_on = 0;
+ } else if (over.type == _GP(play).text_overlay_on) {
+ _GP(play).text_overlay_on = 0;
+ if (_GP(play).speech_text_scover)
+ invalidate_and_subref(over, _GP(play).speech_text_scover);
+ }
dispose_overlay(over);
- if (over.type == _GP(play).complete_overlay_on) _GP(play).complete_overlay_on = 0;
- if (over.type == _GP(play).text_overlay_on) _GP(play).text_overlay_on = 0;
_G(numscreenover)--;
for (int i = over_idx; i < _G(numscreenover); ++i)
_G(screenover)[i] = _G(screenover)[i + 1];
- // if an overlay before the sierra-style speech one is removed,
- // update the index
+ // if an overlay before the sierra-style speech one is removed, update the index
if (_G(face_talking) > over_idx)
_G(face_talking)--;
}
@@ -192,8 +220,6 @@ int add_screen_overlay(int x, int y, int type, Bitmap *piccy, bool alphaChannel)
}
int add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel) {
- if (type == OVER_COMPLETE) _GP(play).complete_overlay_on = type;
- if (type == OVER_TEXTMSG || type == OVER_TEXTSPEECH) _GP(play).text_overlay_on = type;
if (type == OVER_CUSTOM) {
// find an unused custom ID; TODO: find a better approach!
for (int id = OVER_CUSTOM + 1; id < OVER_CUSTOM + 100; ++id) {
@@ -203,6 +229,7 @@ int add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic_of
}
}
}
+
ScreenOverlay &over = _G(screenover)[_G(numscreenover)++];
over.pic = piccy;
over.bmp = _G(gfxDriver)->CreateDDBFromBitmap(piccy, alphaChannel);
@@ -216,11 +243,20 @@ int add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic_of
over.associatedOverlayHandle = 0;
over.hasAlphaChannel = alphaChannel;
over.positionRelativeToScreen = true;
+ // TODO: move these custom settings outside of this function
+ if (type == OVER_COMPLETE) _GP(play).complete_overlay_on = type;
+ else if (type == OVER_TEXTMSG || type == OVER_TEXTSPEECH) {
+ _GP(play).text_overlay_on = type;
+ // only make script object for blocking speech now, because messagebox blocks all script
+ // and therefore cannot be accessed, so no practical reason for that atm
+ if (type == OVER_TEXTSPEECH)
+ _GP(play).speech_text_scover = create_scriptobj_addref(over);
+ } else if (type == OVER_PICTURE) {
+ _GP(play).speech_text_scover = create_scriptobj_addref(over);
+ }
return _G(numscreenover) - 1;
}
-
-
void get_overlay_position(const ScreenOverlay &over, int *x, int *y) {
int tdxp, tdyp;
const Rect &ui_view = _GP(play).GetUIViewport();
diff --git a/engines/ags/engine/ac/overlay.h b/engines/ags/engine/ac/overlay.h
index 0bc07f0985..c6e8ccfecd 100644
--- a/engines/ags/engine/ac/overlay.h
+++ b/engines/ags/engine/ac/overlay.h
@@ -54,6 +54,8 @@ void get_overlay_position(const ScreenOverlay &over, int *x, int *y);
int add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, bool alphaChannel = false);
int add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel = false);
void remove_screen_overlay_index(int over_idx);
+// Creates and registers a managed script object for existing overlay object
+ScriptOverlay *create_scriptobj_for_overlay(ScreenOverlay &over);
void recreate_overlay_ddbs();
} // namespace AGS3
diff --git a/engines/ags/engine/ac/speech.cpp b/engines/ags/engine/ac/speech.cpp
index a3eb1b035a..56ec8e0747 100644
--- a/engines/ags/engine/ac/speech.cpp
+++ b/engines/ags/engine/ac/speech.cpp
@@ -31,6 +31,7 @@
#include "ags/shared/debugging/out.h"
#include "ags/engine/script/script_api.h"
#include "ags/engine/script/script_runtime.h"
+#include "ags/engine/ac/dynobj/script_overlay.h"
#include "ags/globals.h"
namespace AGS3 {
@@ -86,6 +87,10 @@ SkipSpeechStyle internal_skip_speech_to_user(int internal_val) {
//
//=============================================================================
+ScriptOverlay *Speech_GetTextOverlay() {
+ return _GP(play).speech_text_scover;
+}
+
RuntimeScriptValue Sc_Speech_GetAnimationStopTimeMargin(const RuntimeScriptValue *params, int32_t param_count) {
API_VARGET_INT(_GP(play).close_mouth_speech_time);
}
@@ -186,6 +191,10 @@ RuntimeScriptValue Sc_Speech_GetVoiceMode(const RuntimeScriptValue *params, int3
API_SCALL_INT(GetVoiceMode);
}
+RuntimeScriptValue Sc_Speech_GetTextOverlay(const RuntimeScriptValue *params, int32_t param_count) {
+ API_SCALL_OBJAUTO(ScriptOverlay, Speech_GetTextOverlay);
+}
+
extern RuntimeScriptValue Sc_SetVoiceMode(const RuntimeScriptValue *params, int32_t param_count);
void RegisterSpeechAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) {
@@ -212,6 +221,7 @@ void RegisterSpeechAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) {
ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment_Old);
else
ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment);
+ ccAddExternalStaticFunction("Speech::get_TextOverlay", Sc_Speech_GetTextOverlay);
ccAddExternalStaticFunction("Speech::get_UseGlobalSpeechAnimationDelay", Sc_Speech_GetUseGlobalSpeechAnimationDelay);
ccAddExternalStaticFunction("Speech::set_UseGlobalSpeechAnimationDelay", Sc_Speech_SetUseGlobalSpeechAnimationDelay);
ccAddExternalStaticFunction("Speech::get_VoiceMode", Sc_Speech_GetVoiceMode);
Commit: 217e55e2d92b10c95a6c8a992f0ccaf3863a0243
https://github.com/scummvm/scummvm/commit/217e55e2d92b10c95a6c8a992f0ccaf3863a0243
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:37-07:00
Commit Message:
AGS: Speech.PortraitOverlay for accessing speech portrait overlay
>From upstream 7e9d785262915112d5c4d3f435ef33e22de95fc7
Changed paths:
engines/ags/engine/ac/game_state.h
engines/ags/engine/ac/overlay.cpp
engines/ags/engine/ac/speech.cpp
diff --git a/engines/ags/engine/ac/game_state.h b/engines/ags/engine/ac/game_state.h
index 2ffc72ec46..e9c9a6d32f 100644
--- a/engines/ags/engine/ac/game_state.h
+++ b/engines/ags/engine/ac/game_state.h
@@ -255,6 +255,8 @@ struct GameState {
int text_overlay_on = 0;
// Blocking speech overlay managed object, for accessing in scripts
ScriptOverlay *speech_text_scover = nullptr;
+ // Speech portrait overlay managed object
+ ScriptOverlay *speech_face_scover = nullptr;
int shake_screen_yoff = 0; // y offset of the shaking screen
diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp
index e6466d6e6e..cc858967dd 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -183,18 +183,24 @@ static void dispose_overlay(ScreenOverlay &over) {
void remove_screen_overlay_index(int over_idx) {
ScreenOverlay &over = _G(screenover)[over_idx];
+ // TODO: move these custom settings outside of this function
if (over.type == _GP(play).complete_overlay_on) {
_GP(play).complete_overlay_on = 0;
} else if (over.type == _GP(play).text_overlay_on) {
- _GP(play).text_overlay_on = 0;
if (_GP(play).speech_text_scover)
invalidate_and_subref(over, _GP(play).speech_text_scover);
+ _GP(play).text_overlay_on = 0;
+ } else if (over.type == OVER_PICTURE) {
+ if (_GP(play).speech_face_scover)
+ invalidate_and_subref(over, _GP(play).speech_face_scover);
+ _G(face_talking) = -1;
}
dispose_overlay(over);
_G(numscreenover)--;
for (int i = over_idx; i < _G(numscreenover); ++i)
_G(screenover)[i] = _G(screenover)[i + 1];
// if an overlay before the sierra-style speech one is removed, update the index
+ // TODO: this is bad, need more generic system to store overlay references
if (_G(face_talking) > over_idx)
_G(face_talking)--;
}
@@ -252,7 +258,7 @@ int add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic_of
if (type == OVER_TEXTSPEECH)
_GP(play).speech_text_scover = create_scriptobj_addref(over);
} else if (type == OVER_PICTURE) {
- _GP(play).speech_text_scover = create_scriptobj_addref(over);
+ _GP(play).speech_face_scover = create_scriptobj_addref(over);
}
return _G(numscreenover) - 1;
}
diff --git a/engines/ags/engine/ac/speech.cpp b/engines/ags/engine/ac/speech.cpp
index 56ec8e0747..ab6cb0178d 100644
--- a/engines/ags/engine/ac/speech.cpp
+++ b/engines/ags/engine/ac/speech.cpp
@@ -91,6 +91,10 @@ ScriptOverlay *Speech_GetTextOverlay() {
return _GP(play).speech_text_scover;
}
+ScriptOverlay *Speech_GetPortraitOverlay() {
+ return _GP(play).speech_face_scover;
+}
+
RuntimeScriptValue Sc_Speech_GetAnimationStopTimeMargin(const RuntimeScriptValue *params, int32_t param_count) {
API_VARGET_INT(_GP(play).close_mouth_speech_time);
}
@@ -195,6 +199,10 @@ RuntimeScriptValue Sc_Speech_GetTextOverlay(const RuntimeScriptValue *params, in
API_SCALL_OBJAUTO(ScriptOverlay, Speech_GetTextOverlay);
}
+RuntimeScriptValue Sc_Speech_GetPortraitOverlay(const RuntimeScriptValue *params, int32_t param_count) {
+ API_SCALL_OBJAUTO(ScriptOverlay, Speech_GetPortraitOverlay);
+}
+
extern RuntimeScriptValue Sc_SetVoiceMode(const RuntimeScriptValue *params, int32_t param_count);
void RegisterSpeechAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) {
@@ -206,6 +214,7 @@ void RegisterSpeechAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) {
ccAddExternalStaticFunction("Speech::set_DisplayPostTimeMs", Sc_Speech_SetDisplayPostTimeMs);
ccAddExternalStaticFunction("Speech::get_GlobalSpeechAnimationDelay", Sc_Speech_GetGlobalSpeechAnimationDelay);
ccAddExternalStaticFunction("Speech::set_GlobalSpeechAnimationDelay", Sc_Speech_SetGlobalSpeechAnimationDelay);
+ ccAddExternalStaticFunction("Speech::get_PortraitOverlay", Sc_Speech_GetPortraitOverlay);
ccAddExternalStaticFunction("Speech::get_PortraitXOffset", Sc_Speech_GetPortraitXOffset);
ccAddExternalStaticFunction("Speech::set_PortraitXOffset", Sc_Speech_SetPortraitXOffset);
ccAddExternalStaticFunction("Speech::get_PortraitY", Sc_Speech_GetPortraitY);
Commit: 65f992979e99590b0da44dc4ecfc26a50b8549b8
https://github.com/scummvm/scummvm/commit/65f992979e99590b0da44dc4ecfc26a50b8549b8
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:38-07:00
Commit Message:
AGS: Implemented Game.BlockingWaitSkipped
>From upstream ce6bd0173f668932a0a5cab41119d2a476f7e73c
Changed paths:
engines/ags/engine/ac/display.cpp
engines/ags/engine/ac/game.cpp
engines/ags/engine/ac/game_state.cpp
engines/ags/engine/ac/game_state.h
engines/ags/engine/ac/global_game.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/display.cpp b/engines/ags/engine/ac/display.cpp
index 0a1b94be89..d1baabd78d 100644
--- a/engines/ags/engine/ac/display.cpp
+++ b/engines/ags/engine/ac/display.cpp
@@ -268,6 +268,7 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int
// If fast-forwarding, then skip immediately
if (_GP(play).fast_forward) {
remove_screen_overlay(OVER_TEXTMSG);
+ _GP(play).SetWaitSkipResult(SKIP_AUTOTIMER);
_GP(play).messagetime = -1;
return 0;
}
@@ -290,16 +291,20 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int
check_skip_cutscene_mclick(mbut);
if (_GP(play).fast_forward)
break;
- if (skip_setting & SKIP_MOUSECLICK && !_GP(play).IsIgnoringInput())
+ if (skip_setting & SKIP_MOUSECLICK && !_GP(play).IsIgnoringInput()) {
+ _GP(play).SetWaitSkipResult(SKIP_MOUSECLICK, mbut);
break;
+ }
}
KeyInput kp;
if (run_service_key_controls(kp)) {
check_skip_cutscene_keypress(kp.Key);
if (_GP(play).fast_forward)
break;
- if ((skip_setting & SKIP_KEYPRESS) && !_GP(play).IsIgnoringInput())
+ if ((skip_setting & SKIP_KEYPRESS) && !_GP(play).IsIgnoringInput()) {
+ _GP(play).SetWaitSkipResult(SKIP_KEYPRESS, kp.Key);
break;
+ }
}
update_polled_stuff_if_runtime();
@@ -321,6 +326,7 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int
}
// Test for the timed auto-skip
if ((countdown < 1) && (skip_setting & SKIP_AUTOTIMER)) {
+ _GP(play).SetWaitSkipResult(SKIP_AUTOTIMER);
_GP(play).SetIgnoreInput(_GP(play).ignore_user_input_after_text_timeout_ms);
break;
}
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index 9546948a0d..ddc28902a4 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -752,6 +752,10 @@ void Game_SimulateKeyPress(int key) {
ags_simulate_keypress(static_cast<eAGSKeyCode>(key));
}
+int Game_BlockingWaitSkipped() {
+ return _GP(play).GetWaitSkipResult();
+}
+
//=============================================================================
// save game functions
@@ -1093,8 +1097,10 @@ void start_skipping_cutscene() {
remove_popup_interface(_G(ifacepopped));
// if a text message is currently displayed, remove it
- if (_GP(play).text_overlay_on > 0)
+ if (_GP(play).text_overlay_on > 0) {
remove_screen_overlay(_GP(play).text_overlay_on);
+ _GP(play).SetWaitSkipResult(SKIP_AUTOTIMER);
+ }
}
bool check_skip_cutscene_keypress(int kgn) {
@@ -1722,6 +1728,10 @@ RuntimeScriptValue Sc_Game_SimulateKeyPress(const RuntimeScriptValue *params, in
API_SCALL_VOID_PINT(Game_SimulateKeyPress);
}
+RuntimeScriptValue Sc_Game_BlockingWaitSkipped(const RuntimeScriptValue *params, int32_t param_count) {
+ API_SCALL_INT(Game_BlockingWaitSkipped);
+}
+
void RegisterGameAPI() {
ccAddExternalStaticFunction("Game::IsAudioPlaying^1", Sc_Game_IsAudioPlaying);
ccAddExternalStaticFunction("Game::SetAudioTypeSpeechVolumeDrop^2", Sc_Game_SetAudioTypeSpeechVolumeDrop);
@@ -1774,6 +1784,7 @@ void RegisterGameAPI() {
ccAddExternalStaticFunction("Game::IsPluginLoaded", Sc_Game_IsPluginLoaded);
ccAddExternalStaticFunction("Game::PlayVoiceClip", Sc_Game_PlayVoiceClip);
ccAddExternalStaticFunction("Game::SimulateKeyPress", Sc_Game_SimulateKeyPress);
+ ccAddExternalStaticFunction("Game::get_BlockingWaitSkipped", Sc_Game_BlockingWaitSkipped);
ccAddExternalStaticFunction("Game::get_Camera", Sc_Game_GetCamera);
ccAddExternalStaticFunction("Game::get_CameraCount", Sc_Game_GetCameraCount);
diff --git a/engines/ags/engine/ac/game_state.cpp b/engines/ags/engine/ac/game_state.cpp
index 42d06aacde..ed84c5e33a 100644
--- a/engines/ags/engine/ac/game_state.cpp
+++ b/engines/ags/engine/ac/game_state.cpp
@@ -370,6 +370,20 @@ void GameState::ClearIgnoreInput() {
_ignoreUserInputUntilTime = AGS_Clock::now();
}
+void GameState::SetWaitSkipResult(int how, int data) {
+ wait_counter = 0;
+ wait_skipped_by = how;
+ wait_skipped_by_data = data;
+}
+
+int GameState::GetWaitSkipResult() const {
+ switch (wait_skipped_by) {
+ case SKIP_KEYPRESS: return wait_skipped_by_data;
+ case SKIP_MOUSECLICK: return -(wait_skipped_by_data + 1); // convert to 1-based code and negate
+ default: return 0;
+ }
+}
+
bool GameState::IsBlockingVoiceSpeech() const {
return speech_has_voice && speech_voice_blocking;
}
diff --git a/engines/ags/engine/ac/game_state.h b/engines/ags/engine/ac/game_state.h
index e9c9a6d32f..370f1ceddf 100644
--- a/engines/ags/engine/ac/game_state.h
+++ b/engines/ags/engine/ac/game_state.h
@@ -158,8 +158,8 @@ struct GameState {
int bg_frame = 0, bg_anim_delay = 0; // for animating backgrounds
int music_vol_was = 0; // before the volume drop
short wait_counter = 0;
- char wait_skipped_by = 0; // tells how last wait was skipped [not serialized]
- int wait_skipped_by_data = 0; // extended data telling how last wait was skipped [not serialized]
+ char wait_skipped_by = 0; // tells how last blocking wait was skipped [not serialized]
+ int wait_skipped_by_data = 0; // extended data telling how last blocking wait was skipped [not serialized]
short mboundx1 = 0, mboundx2 = 0, mboundy1 = 0, mboundy2 = 0;
int fade_effect = 0;
int bg_frame_locked = 0;
@@ -354,6 +354,14 @@ struct GameState {
// Clears ignore input state
void ClearIgnoreInput();
+ // Set how the last blocking wait was skipped
+ void SetWaitSkipResult(int how, int data = 0);
+ // Returns the code of the latest blocking wait skip method.
+ // * positive value means a key code;
+ // * negative value means a -(mouse code + 1);
+ // * 0 means timeout.
+ int GetWaitSkipResult() const;
+
//
// Voice speech management
//
diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp
index 4c9bc30f6e..36a36df955 100644
--- a/engines/ags/engine/ac/global_game.cpp
+++ b/engines/ags/engine/ac/global_game.cpp
@@ -772,6 +772,7 @@ void SetGraphicalVariable(const char *varName, int p_value) {
int WaitImpl(int skip_type, int nloops) {
_GP(play).wait_counter = nloops;
+ _GP(play).wait_skipped_by = SKIP_NONE;
_GP(play).wait_skipped_by = SKIP_AUTOTIMER; // we set timer flag by default to simplify that case
_GP(play).wait_skipped_by_data = 0;
_GP(play).key_skip_wait = skip_type;
@@ -783,11 +784,7 @@ int WaitImpl(int skip_type, int nloops) {
return (_GP(play).wait_skipped_by & (SKIP_KEYPRESS | SKIP_MOUSECLICK)) != 0 ? 1 : 0;
}
// >= 3.6.0 return positive keycode, negative mouse button code, or 0 as time-out
- switch (_GP(play).wait_skipped_by) {
- case SKIP_KEYPRESS: return _GP(play).wait_skipped_by_data;
- case SKIP_MOUSECLICK: return -(_GP(play).wait_skipped_by_data + 1); // convert to 1-based code and negate
- default: return 0;
- }
+ return _GP(play).GetWaitSkipResult();
}
void scrWait(int nloops) {
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index b381178381..53d7932bff 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -738,6 +738,7 @@ void engine_init_game_settings() {
_GP(play).music_queue_size = 0;
_GP(play).shakesc_length = 0;
_GP(play).wait_counter = 0;
+ _GP(play).SetWaitSkipResult(SKIP_NONE);
_GP(play).key_skip_wait = SKIP_NONE;
_GP(play).cur_music_number = -1;
_GP(play).music_repeat = 1;
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index e275862a03..6054dd0f27 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -208,12 +208,12 @@ static void check_mouse_controls() {
if (_GP(play).fast_forward || _GP(play).IsIgnoringInput()) { /* do nothing if skipping cutscene or input disabled */
} else if ((_GP(play).wait_counter != 0) && (_GP(play).key_skip_wait & SKIP_MOUSECLICK) != 0) {
- _GP(play).wait_counter = 0;
- _GP(play).wait_skipped_by = SKIP_MOUSECLICK;
- _GP(play).wait_skipped_by_data = mbut;
+ _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).cant_skip_speech & SKIP_MOUSECLICK) {
remove_screen_overlay(_GP(play).text_overlay_on);
+ _GP(play).SetWaitSkipResult(SKIP_MOUSECLICK, mbut);
+ }
} else if (!IsInterfaceEnabled()); // blocking cutscene, ignore mouse
else if (pl_run_plugin_hooks(AGSE_MOUSECLICK, mbut + 1)) {
// plugin took the click
@@ -436,16 +436,17 @@ static void check_keyboard_controls() {
// check if it requires a specific keypress
if ((_GP(play).skip_speech_specific_key > 0) &&
(kgn != _GP(play).skip_speech_specific_key)) {
- } else
+ } else {
remove_screen_overlay(_GP(play).text_overlay_on);
+ _GP(play).SetWaitSkipResult(SKIP_KEYPRESS, kgn);
+ }
}
return;
}
if ((_GP(play).wait_counter != 0) && (_GP(play).key_skip_wait & SKIP_KEYPRESS) != 0) {
- _GP(play).wait_counter = -1;
- debug_script_log("Keypress code %d ignored - in Wait", kgn);
+ _GP(play).SetWaitSkipResult(SKIP_KEYPRESS, kgn);
return;
}
diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp
index a7ae9981fe..88b4911cdd 100644
--- a/engines/ags/engine/main/update.cpp
+++ b/engines/ags/engine/main/update.cpp
@@ -261,8 +261,10 @@ void update_speech_and_messages() {
if (_GP(play).messagetime < 1) {
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) {
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: e93845cb0ca66a548f0e498a87b4055c34241bc8
https://github.com/scummvm/scummvm/commit/e93845cb0ca66a548f0e498a87b4055c34241bc8
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:38-07:00
Commit Message:
AGS: added eSkipNone to SkipSpeechStyle
>From upstream 67f88aed90de1c32fb415e8d0826836fae919bfa
Changed paths:
engines/ags/engine/ac/speech.cpp
engines/ags/engine/ac/speech.h
diff --git a/engines/ags/engine/ac/speech.cpp b/engines/ags/engine/ac/speech.cpp
index ab6cb0178d..e04ea79a59 100644
--- a/engines/ags/engine/ac/speech.cpp
+++ b/engines/ags/engine/ac/speech.cpp
@@ -38,6 +38,8 @@ namespace AGS3 {
int user_to_internal_skip_speech(SkipSpeechStyle userval) {
switch (userval) {
+ case kSkipSpeechNone:
+ return SKIP_NONE;
case kSkipSpeechKeyMouseTime:
return SKIP_AUTOTIMER | SKIP_KEYPRESS | SKIP_MOUSECLICK;
case kSkipSpeechKeyTime:
@@ -54,7 +56,7 @@ int user_to_internal_skip_speech(SkipSpeechStyle userval) {
return SKIP_MOUSECLICK;
default:
quit("user_to_internal_skip_speech: unknown userval");
- return 0;
+ return SKIP_NONE;
}
}
@@ -78,7 +80,7 @@ SkipSpeechStyle internal_skip_speech_to_user(int internal_val) {
return kSkipSpeechMouse;
}
}
- return kSkipSpeechUndefined;
+ return kSkipSpeechNone;
}
//=============================================================================
diff --git a/engines/ags/engine/ac/speech.h b/engines/ags/engine/ac/speech.h
index dd5e3dc1e9..3d2d46edd2 100644
--- a/engines/ags/engine/ac/speech.h
+++ b/engines/ags/engine/ac/speech.h
@@ -26,7 +26,7 @@
namespace AGS3 {
enum SkipSpeechStyle {
- kSkipSpeechUndefined = -1,
+ kSkipSpeechNone = -1,
kSkipSpeechKeyMouseTime = 0,
kSkipSpeechKeyTime = 1,
kSkipSpeechTime = 2,
@@ -35,7 +35,7 @@ enum SkipSpeechStyle {
kSkipSpeechKey = 5,
kSkipSpeechMouse = 6,
- kSkipSpeechFirst = kSkipSpeechKeyMouseTime,
+ kSkipSpeechFirst = kSkipSpeechNone,
kSkipSpeechLast = kSkipSpeechMouse
};
Commit: cf36b34f0d16e17b2a2c96d06c159ca366e430bd
https://github.com/scummvm/scummvm/commit/cf36b34f0d16e17b2a2c96d06c159ca366e430bd
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:38-07:00
Commit Message:
AGS: Implemented Object.ManualScaling and Object.Scaling
>From upstream fe9bf3707afb4c36effc358d8e3eb7834d333fb5
Changed paths:
engines/ags/engine/ac/draw.cpp
engines/ags/engine/ac/object.cpp
engines/ags/engine/ac/room.cpp
engines/ags/engine/ac/room_object.cpp
engines/ags/engine/ac/room_object.h
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 1a76213273..f85c813cf7 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -1240,22 +1240,22 @@ int construct_object_gfx(int aa, int *drawnWidth, int *drawnHeight, bool alwaysU
int zoom_level = 100;
// calculate the zoom level
- if (_G(objs)[aa].flags & OBJF_USEROOMSCALING) {
+ if ((_G(objs)[aa].flags & OBJF_USEROOMSCALING) == 0) {
+ zoom_level = _G(objs)[aa].zoom;
+ } else {
int onarea = get_walkable_area_at_location(_G(objs)[aa].x, _G(objs)[aa].y);
if ((onarea <= 0) && (_GP(thisroom).WalkAreas[0].ScalingFar == 0)) {
// just off the edge of an area -- use the scaling we had
// while on the area
- zoom_level = _G(objs)[aa].last_zoom;
+ zoom_level = _G(objs)[aa].zoom;
} else
zoom_level = get_area_scaling(onarea, _G(objs)[aa].x, _G(objs)[aa].y);
-
- if (zoom_level != 100)
- scale_sprite_size(_G(objs)[aa].num, zoom_level, &sprwidth, &sprheight);
-
}
- // save the zoom level for next time
- _G(objs)[aa].last_zoom = zoom_level;
+
+ if (zoom_level != 100)
+ scale_sprite_size(_G(objs)[aa].num, zoom_level, &sprwidth, &sprheight);
+ _G(objs)[aa].zoom = zoom_level;
// save width/height into parameters if requested
if (drawnWidth)
@@ -1423,7 +1423,7 @@ void prepare_objects_for_drawing() {
usebasel += _GP(thisroom).Height;
}
} else if (_G(walkBehindMethod) == DrawAsSeparateCharSprite) {
- sort_out_char_sprite_walk_behind(useindx, atxp, atyp, usebasel, _G(objs)[aa].last_zoom, _G(objs)[aa].last_width, _G(objs)[aa].last_height);
+ sort_out_char_sprite_walk_behind(useindx, atxp, atyp, usebasel, _G(objs)[aa].zoom, _G(objs)[aa].last_width, _G(objs)[aa].last_height);
} else if ((!actspsIntact) && (_G(walkBehindMethod) == DrawOverCharSprite)) {
sort_out_walk_behinds(_G(actsps)[useindx], atxp, atyp, usebasel);
}
@@ -1546,10 +1546,12 @@ void prepare_characters_for_drawing() {
onarea = get_walkable_area_at_character(aa);
_G(our_eip) = 332;
+ // calculates the zoom level
if (chin->flags & CHF_MANUALSCALING) // character ignores scaling
zoom_level = _G(charextra)[aa].zoom;
else if ((onarea <= 0) && (_GP(thisroom).WalkAreas[0].ScalingFar == 0)) {
zoom_level = _G(charextra)[aa].zoom;
+ // NOTE: room objects don't have this fix
if (zoom_level == 0)
zoom_level = 100;
} else
diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp
index cc04f39096..a15cc5ddf1 100644
--- a/engines/ags/engine/ac/object.cpp
+++ b/engines/ags/engine/ac/object.cpp
@@ -321,16 +321,19 @@ int Object_GetClickable(ScriptObject *objj) {
return 1;
}
+void Object_SetManualScaling(ScriptObject *objj, bool on) {
+ if (on) _G(objs)[objj->id].flags &= ~OBJF_USEROOMSCALING;
+ else _G(objs)[objj->id].flags |= OBJF_USEROOMSCALING;
+ // clear the cache
+ _G(objcache)[objj->id].ywas = -9999;
+}
+
void Object_SetIgnoreScaling(ScriptObject *objj, int newval) {
if (!is_valid_object(objj->id))
quit("!Object.IgnoreScaling: Invalid object specified");
-
- _G(objs)[objj->id].flags &= ~OBJF_USEROOMSCALING;
- if (!newval)
- _G(objs)[objj->id].flags |= OBJF_USEROOMSCALING;
-
- // clear the cache
- _G(objcache)[objj->id].ywas = -9999;
+ if (newval)
+ _G(objs)[objj->id].zoom = 100; // compatibility, for before manual scaling existed
+ Object_SetManualScaling(objj, newval != 0);
}
int Object_GetIgnoreScaling(ScriptObject *objj) {
@@ -342,6 +345,22 @@ int Object_GetIgnoreScaling(ScriptObject *objj) {
return 1;
}
+int Object_GetScaling(ScriptObject *objj) {
+ return _G(objs)[objj->id].zoom;
+}
+
+void Object_SetScaling(ScriptObject *objj, int zoomlevel) {
+ if ((_G(objs)[objj->id].flags & OBJF_USEROOMSCALING) != 0) {
+ debug_script_warn("Object.Scaling: cannot set property unless ManualScaling is enabled");
+ return;
+ }
+ int zoom_fixed = Math::Clamp(zoomlevel, 1, (int)(INT16_MAX)); // RoomObject.zoom is int16
+ if (zoomlevel != zoom_fixed)
+ debug_script_warn("Object.Scaling: scaling level must be between 1 and %d%%, asked for: %d",
+ (int)(INT16_MAX), zoomlevel);
+ _G(objs)[objj->id].zoom = zoom_fixed;
+}
+
void Object_SetSolid(ScriptObject *objj, int solid) {
_G(objs)[objj->id].flags &= ~OBJF_SOLID;
if (solid)
@@ -758,6 +777,10 @@ RuntimeScriptValue Sc_Object_GetLoop(void *self, const RuntimeScriptValue *param
API_OBJCALL_INT(ScriptObject, Object_GetLoop);
}
+RuntimeScriptValue Sc_Object_SetManualScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+ API_OBJCALL_VOID_PBOOL(ScriptObject, Object_SetManualScaling);
+}
+
// int (ScriptObject *objj)
RuntimeScriptValue Sc_Object_GetMoving(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_INT(ScriptObject, Object_GetMoving);
@@ -768,6 +791,14 @@ RuntimeScriptValue Sc_Object_GetName_New(void *self, const RuntimeScriptValue *p
API_CONST_OBJCALL_OBJ(ScriptObject, const char, _GP(myScriptStringImpl), Object_GetName_New);
}
+RuntimeScriptValue Sc_Object_GetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+ API_OBJCALL_INT(ScriptObject, Object_GetScaling);
+}
+
+RuntimeScriptValue Sc_Object_SetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+ API_OBJCALL_VOID_PINT(ScriptObject, Object_SetScaling);
+}
+
// int (ScriptObject *objj)
RuntimeScriptValue Sc_Object_GetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_INT(ScriptObject, Object_GetSolid);
@@ -869,9 +900,12 @@ void RegisterObjectAPI() {
ccAddExternalObjectFunction("Object::get_IgnoreWalkbehinds", Sc_Object_GetIgnoreWalkbehinds);
ccAddExternalObjectFunction("Object::set_IgnoreWalkbehinds", Sc_Object_SetIgnoreWalkbehinds);
ccAddExternalObjectFunction("Object::get_Loop", Sc_Object_GetLoop);
+ ccAddExternalObjectFunction("Object::get_ManualScaling", Sc_Object_GetIgnoreScaling);
+ ccAddExternalObjectFunction("Object::set_ManualScaling", Sc_Object_SetManualScaling);
ccAddExternalObjectFunction("Object::get_Moving", Sc_Object_GetMoving);
ccAddExternalObjectFunction("Object::get_Name", Sc_Object_GetName_New);
- ccAddExternalObjectFunction("Object::get_Solid", Sc_Object_GetSolid);
+ ccAddExternalObjectFunction("Object::get_Scaling", Sc_Object_GetScaling);
+ ccAddExternalObjectFunction("Object::set_Scaling", Sc_Object_SetScaling);
ccAddExternalObjectFunction("Object::set_Solid", Sc_Object_SetSolid);
ccAddExternalObjectFunction("Object::get_Transparency", Sc_Object_GetTransparency);
ccAddExternalObjectFunction("Object::set_Transparency", Sc_Object_SetTransparency);
diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp
index 9cbf56cd7e..8725c36686 100644
--- a/engines/ags/engine/ac/room.cpp
+++ b/engines/ags/engine/ac/room.cpp
@@ -573,7 +573,7 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
_G(croom)->obj[cc].moving = -1;
_G(croom)->obj[cc].flags = _GP(thisroom).Objects[cc].Flags;
_G(croom)->obj[cc].baseline = -1;
- _G(croom)->obj[cc].last_zoom = 100;
+ _G(croom)->obj[cc].zoom = 100;
_G(croom)->obj[cc].last_width = 0;
_G(croom)->obj[cc].last_height = 0;
_G(croom)->obj[cc].blocking_width = 0;
diff --git a/engines/ags/engine/ac/room_object.cpp b/engines/ags/engine/ac/room_object.cpp
index f311d49d01..6b1dd69372 100644
--- a/engines/ags/engine/ac/room_object.cpp
+++ b/engines/ags/engine/ac/room_object.cpp
@@ -36,17 +36,13 @@ namespace AGS3 {
using namespace AGS::Shared;
-
-
-
-
RoomObject::RoomObject() {
x = y = 0;
transparent = 0;
tint_r = tint_g = 0;
tint_b = tint_level = 0;
tint_light = 0;
- last_zoom = 0;
+ zoom = 0;
last_width = last_height = 0;
num = 0;
baseline = 0;
diff --git a/engines/ags/engine/ac/room_object.h b/engines/ags/engine/ac/room_object.h
index 1c8b9697e3..912a8d3e1f 100644
--- a/engines/ags/engine/ac/room_object.h
+++ b/engines/ags/engine/ac/room_object.h
@@ -51,7 +51,7 @@ struct RoomObject {
short tint_r, tint_g; // specific object tint
short tint_b, tint_level;
short tint_light;
- short last_zoom; // zoom level last time
+ short zoom; // zoom level, either manual or from the current area
short last_width, last_height; // width/height last time drawn
uint16_t num; // sprite slot number
short baseline; // <=0 to use Y co-ordinate; >0 for specific baseline
Commit: 28102f13ab3f6fe4979f272e8e8500b8d3d47fc7
https://github.com/scummvm/scummvm/commit/28102f13ab3f6fe4979f272e8e8500b8d3d47fc7
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:38-07:00
Commit Message:
AGS: allow Character.Scaling full range (1-32767)
>From upstream fe9b19e2d9868b3c953aa4b71c44be3c712987b7
Changed paths:
engines/ags/engine/ac/character.cpp
diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp
index 5433b8cc70..114219c485 100644
--- a/engines/ags/engine/ac/character.cpp
+++ b/engines/ags/engine/ac/character.cpp
@@ -1384,10 +1384,12 @@ void Character_SetScaling(CharacterInfo *chaa, int zoomlevel) {
debug_script_warn("Character.Scaling: cannot set property unless ManualScaling is enabled");
return;
}
- if ((zoomlevel < 5) || (zoomlevel > 200))
- quit("!Character.Scaling: scaling level must be between 5 and 200%");
+ int zoom_fixed = Math::Clamp(zoomlevel, 1, (int)(INT16_MAX)); // CharacterExtras.zoom is int16
+ if (zoomlevel != zoom_fixed)
+ debug_script_warn("Character.Scaling: scaling level must be between 1 and %d%%, asked for: %d",
+ (int)(INT16_MAX), zoomlevel);
- _G(charextra)[chaa->index_id].zoom = zoomlevel;
+ _G(charextra)[chaa->index_id].zoom = zoom_fixed;
}
int Character_GetSolid(CharacterInfo *chaa) {
Commit: 60c7f3351610e5794e0cb8dcf8187ced3bf51b39
https://github.com/scummvm/scummvm/commit/60c7f3351610e5794e0cb8dcf8187ced3bf51b39
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-27T22:03:39-07:00
Commit Message:
AGS: Update engine sync point comments
>From upstream 4bb97d6d318fdd1a8d2e86e0b8b0457bd5f939d0
Changed paths:
engines/ags/ags.h
diff --git a/engines/ags/ags.h b/engines/ags/ags.h
index 4f009fb6dd..146de292c1 100644
--- a/engines/ags/ags.h
+++ b/engines/ags/ags.h
@@ -50,8 +50,8 @@ namespace AGS {
* @brief Engine to run Adventure Game Studio games.
*/
-/* Synced up to upstream:
- * 4e2df949ff36bbb6d08e402586dc8c2bb02ecad9
+/* Synced up to upstream: 3.6.0.5
+ * 4bb97d6d318fdd1a8d2e86e0b8b0457bd5f939d0
*/
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 200
More information about the Scummvm-git-logs
mailing list