aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/EventDispatcher.cpp26
-rw-r--r--common/EventMapper.cpp92
-rw-r--r--common/archive.cpp22
-rw-r--r--common/archive.h22
-rw-r--r--common/array.h74
-rw-r--r--common/config-file.cpp6
-rw-r--r--common/config-manager.cpp6
-rw-r--r--common/endian.h10
-rw-r--r--common/events.h60
-rw-r--r--common/fft.cpp2
-rw-r--r--common/forbidden.h47
-rw-r--r--common/fs.cpp16
-rw-r--r--common/fs.h8
-rw-r--r--common/gui_options.cpp115
-rw-r--r--common/gui_options.h85
-rw-r--r--common/hash-str.h4
-rw-r--r--common/hashmap.h91
-rw-r--r--common/huffman.h2
-rw-r--r--common/keyboard.h21
-rw-r--r--common/language.cpp125
-rw-r--r--common/language.h86
-rw-r--r--common/list.h7
-rw-r--r--common/list_intern.h2
-rw-r--r--common/localization.h2
-rw-r--r--common/macresman.cpp21
-rw-r--r--common/macresman.h7
-rw-r--r--common/math.h2
-rw-r--r--common/memorypool.cpp2
-rw-r--r--common/memorypool.h2
-rw-r--r--common/module.mk5
-rw-r--r--common/platform.cpp107
-rw-r--r--common/platform.h80
-rw-r--r--common/ptr.h4
-rw-r--r--common/quicktime.cpp32
-rw-r--r--common/quicktime.h4
-rw-r--r--common/rect.h7
-rw-r--r--common/rendermode.cpp122
-rw-r--r--common/rendermode.h73
-rw-r--r--common/scummsys.h7
-rw-r--r--common/serializer.h2
-rw-r--r--common/singleton.h4
-rw-r--r--common/stack.h47
-rw-r--r--common/str.cpp12
-rw-r--r--common/stream.cpp2
-rw-r--r--common/substream.h17
-rw-r--r--common/system.h39
-rw-r--r--common/translation.cpp61
-rw-r--r--common/translation.h19
-rw-r--r--common/unarj.cpp14
-rw-r--r--common/unzip.cpp20
-rw-r--r--common/util.cpp322
-rw-r--r--common/util.h201
-rw-r--r--common/xmlparser.cpp12
-rw-r--r--common/xmlparser.h10
-rw-r--r--common/zlib.cpp9
-rw-r--r--common/zlib.h33
56 files changed, 1532 insertions, 698 deletions
diff --git a/common/EventDispatcher.cpp b/common/EventDispatcher.cpp
index 4e3f671cfd..012a2dfce5 100644
--- a/common/EventDispatcher.cpp
+++ b/common/EventDispatcher.cpp
@@ -48,26 +48,24 @@ void EventDispatcher::dispatch() {
dispatchPoll();
for (List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
- const bool allowMapping = i->source->allowMapping();
-
while (i->source->pollEvent(event)) {
// We only try to process the events via the setup event mapper, when
// we have a setup mapper and when the event source allows mapping.
- if (_mapper && allowMapping) {
- if (_mapper->notifyEvent(event)) {
- // We allow the event mapper to create multiple events, when
- // eating an event.
- while (_mapper->pollEvent(event))
- dispatchEvent(event);
-
- // Try getting another event from the current EventSource.
- continue;
- }
- }
+ assert(_mapper);
+ List<Event> mappedEvents = _mapper->mapEvent(event, i->source);
- dispatchEvent(event);
+ for (List<Event>::iterator j = mappedEvents.begin(); j != mappedEvents.end(); ++j) {
+ const Event mappedEvent = *j;
+ dispatchEvent(mappedEvent);
+ }
}
}
+
+ List<Event> delayedEvents = _mapper->getDelayedEvents();
+ for (List<Event>::iterator k = delayedEvents.begin(); k != delayedEvents.end(); ++k) {
+ const Event delayedEvent = *k;
+ dispatchEvent(delayedEvent);
+ }
}
void EventDispatcher::registerMapper(EventMapper *mapper) {
diff --git a/common/EventMapper.cpp b/common/EventMapper.cpp
new file mode 100644
index 0000000000..5f6771a71d
--- /dev/null
+++ b/common/EventMapper.cpp
@@ -0,0 +1,92 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/events.h"
+
+#include "common/system.h"
+#include "common/textconsole.h"
+
+namespace Common {
+
+List<Event> DefaultEventMapper::mapEvent(const Event &ev, EventSource *source) {
+ List<Event> events;
+ Event mappedEvent;
+ if (ev.type == EVENT_KEYDOWN) {
+ if (ev.kbd.hasFlags(KBD_CTRL) && ev.kbd.keycode == KEYCODE_F5) {
+ mappedEvent.type = EVENT_MAINMENU;
+ }
+#ifdef ENABLE_VKEYBD
+ else if (ev.kbd.keycode == KEYCODE_F7 && ev.kbd.hasFlags(0)) {
+ mappedEvent.type = EVENT_VIRTUAL_KEYBOARD;
+ }
+#endif
+#ifdef ENABLE_KEYMAPPER
+ else if (ev.kbd.keycode == KEYCODE_F8 && ev.kbd.hasFlags(0)) {
+ mappedEvent.type = EVENT_KEYMAPPER_REMAP;
+ }
+#endif
+ }
+
+ // if it didn't get mapped, just pass it through
+ if (mappedEvent.type == EVENT_INVALID)
+ mappedEvent = ev;
+
+#ifdef ENABLE_KEYMAPPER
+ // TODO: this check is not needed post-split
+ if (mappedEvent.type == EVENT_CUSTOM_BACKEND_HARDWARE) {
+ warning("EVENT_CUSTOM_BACKEND_HARDWARE was not mapped");
+ return List<Event>();
+ }
+#endif
+
+ events.push_back(mappedEvent);
+ return events;
+}
+
+
+void DefaultEventMapper::addDelayedEvent(uint32 millis, Event ev) {
+ if (_delayedEvents.empty()) {
+ _delayedEffectiveTime = g_system->getMillis() + millis;
+ millis = 0;
+ }
+ DelayedEventsEntry entry = DelayedEventsEntry(millis, ev);
+ _delayedEvents.push(entry);
+}
+
+List<Event> DefaultEventMapper::getDelayedEvents() {
+ List<Event> events;
+
+ if (_delayedEvents.empty())
+ return events;
+
+ uint32 now = g_system->getMillis();
+
+ while (!_delayedEvents.empty() && now >= _delayedEffectiveTime) {
+ DelayedEventsEntry entry = _delayedEvents.pop();
+ if (!_delayedEvents.empty())
+ _delayedEffectiveTime += _delayedEvents.front().timerOffset;
+ events.push_back(entry.event);
+ }
+ return events;
+}
+
+} // namespace Common
diff --git a/common/archive.cpp b/common/archive.cpp
index 954de8bcaa..1323f14805 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -27,7 +27,7 @@
namespace Common {
-GenericArchiveMember::GenericArchiveMember(String name, Archive *parent)
+GenericArchiveMember::GenericArchiveMember(const String &name, const Archive *parent)
: _parent(parent), _name(name) {
}
@@ -40,14 +40,14 @@ SeekableReadStream *GenericArchiveMember::createReadStream() const {
}
-int Archive::listMatchingMembers(ArchiveMemberList &list, const String &pattern) {
+int Archive::listMatchingMembers(ArchiveMemberList &list, const String &pattern) const {
// Get all "names" (TODO: "files" ?)
ArchiveMemberList allNames;
listMembers(allNames);
int matches = 0;
- ArchiveMemberList::iterator it = allNames.begin();
+ ArchiveMemberList::const_iterator it = allNames.begin();
for ( ; it != allNames.end(); ++it) {
// TODO: We match case-insenstivie for now, our API does not define whether that's ok or not though...
// For our use case case-insensitive is probably what we want to have though.
@@ -206,11 +206,11 @@ void SearchSet::setPriority(const String &name, int priority) {
insert(node);
}
-bool SearchSet::hasFile(const String &name) {
+bool SearchSet::hasFile(const String &name) const {
if (name.empty())
return false;
- ArchiveNodeList::iterator it = _list.begin();
+ ArchiveNodeList::const_iterator it = _list.begin();
for ( ; it != _list.end(); ++it) {
if (it->_arc->hasFile(name))
return true;
@@ -219,31 +219,31 @@ bool SearchSet::hasFile(const String &name) {
return false;
}
-int SearchSet::listMatchingMembers(ArchiveMemberList &list, const String &pattern) {
+int SearchSet::listMatchingMembers(ArchiveMemberList &list, const String &pattern) const {
int matches = 0;
- ArchiveNodeList::iterator it = _list.begin();
+ ArchiveNodeList::const_iterator it = _list.begin();
for ( ; it != _list.end(); ++it)
matches += it->_arc->listMatchingMembers(list, pattern);
return matches;
}
-int SearchSet::listMembers(ArchiveMemberList &list) {
+int SearchSet::listMembers(ArchiveMemberList &list) const {
int matches = 0;
- ArchiveNodeList::iterator it = _list.begin();
+ ArchiveNodeList::const_iterator it = _list.begin();
for ( ; it != _list.end(); ++it)
matches += it->_arc->listMembers(list);
return matches;
}
-ArchiveMemberPtr SearchSet::getMember(const String &name) {
+const ArchiveMemberPtr SearchSet::getMember(const String &name) const {
if (name.empty())
return ArchiveMemberPtr();
- ArchiveNodeList::iterator it = _list.begin();
+ ArchiveNodeList::const_iterator it = _list.begin();
for ( ; it != _list.end(); ++it) {
if (it->_arc->hasFile(name))
return it->_arc->getMember(name);
diff --git a/common/archive.h b/common/archive.h
index c8e78f9bc8..ffd86d786d 100644
--- a/common/archive.h
+++ b/common/archive.h
@@ -65,10 +65,10 @@ class Archive;
* is destroyed.
*/
class GenericArchiveMember : public ArchiveMember {
- Archive *_parent;
- String _name;
+ const Archive *_parent;
+ const String _name;
public:
- GenericArchiveMember(String name, Archive *parent);
+ GenericArchiveMember(const String &name, const Archive *parent);
String getName() const;
SeekableReadStream *createReadStream() const;
};
@@ -88,7 +88,7 @@ public:
* Patterns are not allowed, as this is meant to be a quick File::exists()
* replacement.
*/
- virtual bool hasFile(const String &name) = 0;
+ virtual bool hasFile(const String &name) const = 0;
/**
* Add all members of the Archive matching the specified pattern to list.
@@ -96,7 +96,7 @@ public:
*
* @return the number of members added to list
*/
- virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern);
+ virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern) const;
/**
* Add all members of the Archive to list.
@@ -104,12 +104,12 @@ public:
*
* @return the number of names added to list
*/
- virtual int listMembers(ArchiveMemberList &list) = 0;
+ virtual int listMembers(ArchiveMemberList &list) const = 0;
/**
* Returns a ArchiveMember representation of the given file.
*/
- virtual ArchiveMemberPtr getMember(const String &name) = 0;
+ virtual const ArchiveMemberPtr getMember(const String &name) const = 0;
/**
* Create a stream bound to a member with the specified name in the
@@ -230,11 +230,11 @@ public:
*/
void setPriority(const String& name, int priority);
- virtual bool hasFile(const String &name);
- virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern);
- virtual int listMembers(ArchiveMemberList &list);
+ virtual bool hasFile(const String &name) const;
+ virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern) const;
+ virtual int listMembers(ArchiveMemberList &list) const;
- virtual ArchiveMemberPtr getMember(const String &name);
+ virtual const ArchiveMemberPtr getMember(const String &name) const;
/**
* Implements createReadStreamForMember from Archive base class. The current policy is
diff --git a/common/array.h b/common/array.h
index ef0ee27f24..a2c3023362 100644
--- a/common/array.h
+++ b/common/array.h
@@ -24,7 +24,7 @@
#include "common/scummsys.h"
#include "common/algorithm.h"
-#include "common/textconsole.h" // For error()
+#include "common/textconsole.h" // For error()
#include "common/memory.h"
namespace Common {
@@ -42,17 +42,19 @@ namespace Common {
*/
template<class T>
class Array {
-protected:
- uint _capacity;
- uint _size;
- T *_storage;
-
public:
typedef T *iterator;
typedef const T *const_iterator;
typedef T value_type;
+ typedef uint size_type;
+
+protected:
+ size_type _capacity;
+ size_type _size;
+ T *_storage;
+
public:
Array() : _capacity(0), _size(0), _storage(0) {}
@@ -67,7 +69,7 @@ public:
* Construct an array by copying data from a regular array.
*/
template<class T2>
- Array(const T2 *data, int n) {
+ Array(const T2 *data, size_type n) {
_size = n;
allocCapacity(n);
uninitialized_copy(data, data + _size, _storage);
@@ -128,19 +130,19 @@ public:
}
- void insert_at(int idx, const T &element) {
- assert(idx >= 0 && (uint)idx <= _size);
+ void insert_at(size_type idx, const T &element) {
+ assert(idx <= _size);
insert_aux(_storage + idx, &element, &element + 1);
}
- void insert_at(int idx, const Array<T> &array) {
- assert(idx >= 0 && (uint)idx <= _size);
+ void insert_at(size_type idx, const Array<T> &array) {
+ assert(idx <= _size);
insert_aux(_storage + idx, array.begin(), array.end());
}
- T remove_at(int idx) {
- assert(idx >= 0 && (uint)idx < _size);
+ T remove_at(size_type idx) {
+ assert(idx < _size);
T tmp = _storage[idx];
copy(_storage + idx + 1, _storage + _size, _storage + idx);
_size--;
@@ -151,17 +153,17 @@ public:
// TODO: insert, remove, ...
- T& operator[](int idx) {
- assert(idx >= 0 && (uint)idx < _size);
+ T &operator[](size_type idx) {
+ assert(idx < _size);
return _storage[idx];
}
- const T& operator[](int idx) const {
- assert(idx >= 0 && (uint)idx < _size);
+ const T &operator[](size_type idx) const {
+ assert(idx < _size);
return _storage[idx];
}
- Array<T>& operator=(const Array<T> &array) {
+ Array<T> &operator=(const Array<T> &array) {
if (this == &array)
return *this;
@@ -173,7 +175,7 @@ public:
return *this;
}
- uint size() const {
+ size_type size() const {
return _size;
}
@@ -193,34 +195,34 @@ public:
return true;
if (_size != other._size)
return false;
- for (uint i = 0; i < _size; ++i) {
+ for (size_type i = 0; i < _size; ++i) {
if (_storage[i] != other._storage[i])
return false;
}
return true;
}
+
bool operator!=(const Array<T> &other) const {
return !(*this == other);
}
-
- iterator begin() {
+ iterator begin() {
return _storage;
}
- iterator end() {
+ iterator end() {
return _storage + _size;
}
- const_iterator begin() const {
+ const_iterator begin() const {
return _storage;
}
- const_iterator end() const {
+ const_iterator end() const {
return _storage + _size;
}
- void reserve(uint newCapacity) {
+ void reserve(size_type newCapacity) {
if (newCapacity <= _capacity)
return;
@@ -234,9 +236,9 @@ public:
}
}
- void resize(uint newSize) {
+ void resize(size_type newSize) {
reserve(newSize);
- for (uint i = _size; i < newSize; ++i)
+ for (size_type i = _size; i < newSize; ++i)
new ((void *)&_storage[i]) T();
_size = newSize;
}
@@ -249,28 +251,28 @@ public:
}
protected:
- static uint roundUpCapacity(uint capacity) {
+ static size_type roundUpCapacity(size_type capacity) {
// Round up capacity to the next power of 2;
// we use a minimal capacity of 8.
- uint capa = 8;
+ size_type capa = 8;
while (capa < capacity)
capa <<= 1;
return capa;
}
- void allocCapacity(uint capacity) {
+ void allocCapacity(size_type capacity) {
_capacity = capacity;
if (capacity) {
_storage = (T *)malloc(sizeof(T) * capacity);
if (!_storage)
- ::error("Common::Array: failure to allocate %u bytes", capacity * (uint)sizeof(T));
+ ::error("Common::Array: failure to allocate %u bytes", capacity * (size_type)sizeof(T));
} else {
_storage = 0;
}
}
- void freeStorage(T *storage, const uint elements) {
- for (uint i = 0; i < elements; ++i)
+ void freeStorage(T *storage, const size_type elements) {
+ for (size_type i = 0; i < elements; ++i)
storage[i].~T();
free(storage);
}
@@ -291,9 +293,9 @@ protected:
iterator insert_aux(iterator pos, const_iterator first, const_iterator last) {
assert(_storage <= pos && pos <= _storage + _size);
assert(first <= last);
- const uint n = last - first;
+ const size_type n = last - first;
if (n) {
- const uint idx = pos - _storage;
+ const size_type idx = pos - _storage;
if (_size + n > _capacity || (_storage <= first && first <= _storage + _size)) {
T *const oldStorage = _storage;
diff --git a/common/config-file.cpp b/common/config-file.cpp
index 81e0ae6b45..4224d7491d 100644
--- a/common/config-file.cpp
+++ b/common/config-file.cpp
@@ -30,7 +30,7 @@ namespace Common {
bool ConfigFile::isValidName(const String &name) {
const char *p = name.c_str();
- while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_' || *p == '.'))
+ while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.'))
p++;
return *p == 0;
}
@@ -108,7 +108,7 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) {
// is, verify that it only consists of alphanumerics,
// periods, dashes and underscores). Mohawk Living Books games
// can have periods in their section names.
- while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_' || *p == '.'))
+ while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.'))
p++;
if (*p == '\0')
@@ -131,7 +131,7 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) {
// Skip leading whitespaces
const char *t = line.c_str();
- while (isspace(static_cast<unsigned char>(*t)))
+ while (isSpace(*t))
t++;
// Skip empty lines / lines with only whitespace
diff --git a/common/config-manager.cpp b/common/config-manager.cpp
index c62dee8bea..aaa812bc94 100644
--- a/common/config-manager.cpp
+++ b/common/config-manager.cpp
@@ -29,7 +29,7 @@
static bool isValidDomainName(const Common::String &domName) {
const char *p = domName.c_str();
- while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_'))
+ while (*p && (Common::isAlnum(*p) || *p == '-' || *p == '_'))
p++;
return *p == 0;
}
@@ -187,7 +187,7 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) {
// Get the domain name, and check whether it's valid (that
// is, verify that it only consists of alphanumerics,
// dashes and underscores).
- while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_'))
+ while (*p && (isAlnum(*p) || *p == '-' || *p == '_'))
p++;
if (*p == '\0')
@@ -205,7 +205,7 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) {
// Skip leading whitespaces
const char *t = line.c_str();
- while (isspace(static_cast<unsigned char>(*t)))
+ while (isSpace(*t))
t++;
// Skip empty lines / lines with only whitespace
diff --git a/common/endian.h b/common/endian.h
index 9cb703858a..394437ec67 100644
--- a/common/endian.h
+++ b/common/endian.h
@@ -86,7 +86,7 @@
}
// Test for GCC >= 4.3.0 as this version added the bswap builtin
-#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+#elif GCC_ATLEAST(4, 3)
FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) {
return __builtin_bswap32(a);
@@ -156,7 +156,7 @@
//
// Moreover, we activate this code for GCC >= 3.3 but *only* if unaligned access
// is allowed.
-#if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3 && !defined(SCUMM_NEED_ALIGNMENT)))
+#if GCC_ATLEAST(4, 0) || (GCC_ATLEAST(3, 3) && !defined(SCUMM_NEED_ALIGNMENT))
FORCEINLINE uint16 READ_UINT16(const void *ptr) {
struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__));
@@ -396,4 +396,10 @@ inline uint32 READ_BE_UINT24(const void *ptr) {
return (b[0] << 16) | (b[1] << 8) | (b[2]);
}
+#ifdef SCUMM_LITTLE_ENDIAN
+#define READ_UINT24(a) READ_LE_UINT24(a)
+#else
+#define READ_UINT24(a) READ_BE_UINT24(a)
+#endif
+
#endif
diff --git a/common/events.h b/common/events.h
index f5ace7481b..7366c51d36 100644
--- a/common/events.h
+++ b/common/events.h
@@ -73,8 +73,23 @@ enum EventType {
* An associated enumerated type can accomplish this.
**/
EVENT_PREDICTIVE_DIALOG = 12
+
+#ifdef ENABLE_KEYMAPPER
+ ,
+ // IMPORTANT NOTE: This is part of the WIP Keymapper. If you plan to use
+ // this, please talk to tsoliman and/or LordHoto.
+ EVENT_CUSTOM_BACKEND_ACTION = 18,
+ EVENT_CUSTOM_BACKEND_HARDWARE = 21,
+ EVENT_GUI_REMAP_COMPLETE_ACTION = 22,
+ EVENT_KEYMAPPER_REMAP = 19
+#endif
+#ifdef ENABLE_VKEYBD
+ ,
+ EVENT_VIRTUAL_KEYBOARD = 20
+#endif
};
+typedef uint32 CustomEventType;
/**
* Data structure for an event. A pointer to an instance of Event
* can be passed to pollEvent.
@@ -99,7 +114,17 @@ struct Event {
*/
Point mouse;
- Event() : type(EVENT_INVALID), synthetic(false) {}
+#ifdef ENABLE_KEYMAPPER
+ // IMPORTANT NOTE: This is part of the WIP Keymapper. If you plan to use
+ // this, please talk to tsoliman and/or LordHoto.
+ CustomEventType customType;
+#endif
+
+ Event() : type(EVENT_INVALID), synthetic(false) {
+#ifdef ENABLE_KEYMAPPER
+ customType = 0;
+#endif
+ }
};
/**
@@ -175,7 +200,7 @@ public:
*
* An observer is supposed to eat the event, with returning true, when
* it wants to prevent other observers from receiving the event.
- * An usage example here is the keymapper:
+ * A usage example here is the keymapper:
* If it processes an Event, it should 'eat' it and create a new
* event, which the EventDispatcher will then catch.
*
@@ -199,10 +224,35 @@ public:
*
* An example for this is the Keymapper.
*/
-class EventMapper : public EventSource, public EventObserver {
+class EventMapper {
public:
- /** For event mappers resulting events should never be mapped */
- bool allowMapping() const { return false; }
+ virtual ~EventMapper() {}
+
+ /**
+ * Map an incoming event to one or more action events
+ */
+ virtual List<Event> mapEvent(const Event &ev, EventSource *source) = 0;
+
+ virtual List<Event> getDelayedEvents() = 0;
+};
+
+class DefaultEventMapper : public EventMapper {
+public:
+ DefaultEventMapper() : _delayedEvents(), _delayedEffectiveTime(0) {}
+ // EventMapper interface
+ virtual List<Event> mapEvent(const Event &ev, EventSource *source);
+ virtual List<Event> getDelayedEvents();
+protected:
+ virtual void addDelayedEvent(uint32 millis, Event ev);
+
+ struct DelayedEventsEntry {
+ const uint32 timerOffset;
+ const Event event;
+ DelayedEventsEntry(const uint32 offset, const Event ev) : timerOffset(offset), event(ev) { }
+ };
+
+ Queue<DelayedEventsEntry> _delayedEvents;
+ uint32 _delayedEffectiveTime;
};
/**
diff --git a/common/fft.cpp b/common/fft.cpp
index 5852698b61..034570964f 100644
--- a/common/fft.cpp
+++ b/common/fft.cpp
@@ -231,7 +231,7 @@ DECL_FFT(14, 16384, 8192, 4096)
DECL_FFT(15, 32768, 16384, 8192)
DECL_FFT(16, 65536, 32768, 16384)
-static void (* const fft_dispatch[])(Complex*) = {
+static void (* const fft_dispatch[])(Complex *) = {
fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024,
fft2048, fft4096, fft8192, fft16384, fft32768, fft65536,
};
diff --git a/common/forbidden.h b/common/forbidden.h
index 95c1a47d65..eec80bba59 100644
--- a/common/forbidden.h
+++ b/common/forbidden.h
@@ -182,7 +182,8 @@
#define putchar(a) FORBIDDEN_SYMBOL_REPLACEMENT
#endif
-
+// mingw-w64 uses [set|long]jmp in system headers
+#ifndef __MINGW64__
#ifndef FORBIDDEN_SYMBOL_EXCEPTION_setjmp
#undef setjmp
#define setjmp(a) FORBIDDEN_SYMBOL_REPLACEMENT
@@ -192,6 +193,7 @@
#undef longjmp
#define longjmp(a,b) FORBIDDEN_SYMBOL_REPLACEMENT
#endif
+#endif // __MINGW64__
#ifndef FORBIDDEN_SYMBOL_EXCEPTION_system
#undef system
@@ -315,6 +317,49 @@
#endif // FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
+
+//
+// Disable various symbols from ctype.h
+//
+#ifndef FORBIDDEN_SYMBOL_EXCEPTION_ctype_h
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_isalnum
+ #undef isalnum
+ #define isalnum(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_isalpha
+ #undef isalpha
+ #define isalpha(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_isdigit
+ #undef isdigit
+ #define isdigit(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_isnumber
+ #undef isnumber
+ #define isnumber(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_islower
+ #undef islower
+ #define islower(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_isspace
+ #undef isspace
+ #define isspace(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+ #ifndef FORBIDDEN_SYMBOL_EXCEPTION_isupper
+ #undef isupper
+ #define isupper(a) FORBIDDEN_SYMBOL_REPLACEMENT
+ #endif
+
+#endif // FORBIDDEN_SYMBOL_EXCEPTION_ctype_h
+
#ifndef FORBIDDEN_SYMBOL_EXCEPTION_mkdir
#undef mkdir
#define mkdir(a,b) FORBIDDEN_SYMBOL_REPLACEMENT
diff --git a/common/fs.cpp b/common/fs.cpp
index 4b56cc4594..0143c936d4 100644
--- a/common/fs.cpp
+++ b/common/fs.cpp
@@ -130,10 +130,10 @@ SeekableReadStream *FSNode::createReadStream() const {
if (!_realNode->exists()) {
warning("FSNode::createReadStream: '%s' does not exist", getName().c_str());
- return false;
+ return 0;
} else if (_realNode->isDirectory()) {
warning("FSNode::createReadStream: '%s' is a directory", getName().c_str());
- return false;
+ return 0;
}
return _realNode->createReadStream();
@@ -197,7 +197,7 @@ FSNode *FSDirectory::lookupCache(NodeCache &cache, const String &name) const {
return 0;
}
-bool FSDirectory::hasFile(const String &name) {
+bool FSDirectory::hasFile(const String &name) const {
if (name.empty() || !_node.isDirectory())
return false;
@@ -205,7 +205,7 @@ bool FSDirectory::hasFile(const String &name) {
return node && node->exists();
}
-ArchiveMemberPtr FSDirectory::getMember(const String &name) {
+const ArchiveMemberPtr FSDirectory::getMember(const String &name) const {
if (name.empty() || !_node.isDirectory())
return ArchiveMemberPtr();
@@ -295,7 +295,7 @@ void FSDirectory::ensureCached() const {
_cached = true;
}
-int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &pattern) {
+int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &pattern) const {
if (!_node.isDirectory())
return 0;
@@ -308,7 +308,7 @@ int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &patt
lowercasePattern.toLowercase();
int matches = 0;
- NodeCache::iterator it = _fileCache.begin();
+ NodeCache::const_iterator it = _fileCache.begin();
for ( ; it != _fileCache.end(); ++it) {
if (it->_key.matchString(lowercasePattern, false, true)) {
list.push_back(ArchiveMemberPtr(new FSNode(it->_value)));
@@ -318,7 +318,7 @@ int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &patt
return matches;
}
-int FSDirectory::listMembers(ArchiveMemberList &list) {
+int FSDirectory::listMembers(ArchiveMemberList &list) const {
if (!_node.isDirectory())
return 0;
@@ -326,7 +326,7 @@ int FSDirectory::listMembers(ArchiveMemberList &list) {
ensureCached();
int files = 0;
- for (NodeCache::iterator it = _fileCache.begin(); it != _fileCache.end(); ++it) {
+ for (NodeCache::const_iterator it = _fileCache.begin(); it != _fileCache.end(); ++it) {
list.push_back(ArchiveMemberPtr(new FSNode(it->_value)));
++files;
}
diff --git a/common/fs.h b/common/fs.h
index aeaa14718e..fadd672bb1 100644
--- a/common/fs.h
+++ b/common/fs.h
@@ -318,23 +318,23 @@ public:
* Checks for existence in the cache. A full match of relative path and filename is needed
* for success.
*/
- virtual bool hasFile(const String &name);
+ virtual bool hasFile(const String &name) const;
/**
* Returns a list of matching file names. Pattern can use GLOB wildcards.
*/
- virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern);
+ virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern) const;
/**
* Returns a list of all the files in the cache.
*/
- virtual int listMembers(ArchiveMemberList &list);
+ virtual int listMembers(ArchiveMemberList &list) const;
/**
* Get a ArchiveMember representation of the specified file. A full match of relative
* path and filename is needed for success.
*/
- virtual ArchiveMemberPtr getMember(const String &name);
+ virtual const ArchiveMemberPtr getMember(const String &name) const;
/**
* Open the specified file. A full match of relative path and filename is needed
diff --git a/common/gui_options.cpp b/common/gui_options.cpp
new file mode 100644
index 0000000000..32a7cc9c41
--- /dev/null
+++ b/common/gui_options.cpp
@@ -0,0 +1,115 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/gui_options.h"
+
+#include "common/config-manager.h"
+#include "common/str.h"
+
+namespace Common {
+
+const struct GameOpt {
+ const char *option;
+ const char *desc;
+} g_gameOptions[] = {
+ { GUIO_NOSUBTITLES, "sndNoSubs" },
+ { GUIO_NOMUSIC, "sndNoMusic" },
+ { GUIO_NOSPEECH, "sndNoSpeech" },
+ { GUIO_NOSFX, "sndNoSFX" },
+ { GUIO_NOMIDI, "sndNoMIDI" },
+
+ { GUIO_NOLAUNCHLOAD, "launchNoLoad" },
+
+ { GUIO_MIDIPCSPK, "midiPCSpk" },
+ { GUIO_MIDICMS, "midiCMS" },
+ { GUIO_MIDIPCJR, "midiPCJr" },
+ { GUIO_MIDIADLIB, "midiAdLib" },
+ { GUIO_MIDIC64, "midiC64" },
+ { GUIO_MIDIAMIGA, "midiAmiga" },
+ { GUIO_MIDIAPPLEIIGS,"midiAppleIIgs" },
+ { GUIO_MIDITOWNS, "midiTowns" },
+ { GUIO_MIDIPC98, "midiPC98" },
+ { GUIO_MIDIMT32, "midiMt32" },
+ { GUIO_MIDIGM, "midiGM" },
+
+ { GUIO_NOASPECT, "noAspect" },
+ { GUIO_EGAUNDITHER, "egaUndither" },
+
+ { GUIO_RENDERHERCGREEN, "hercGreen" },
+ { GUIO_RENDERHERCAMBER, "hercAmber" },
+ { GUIO_RENDERCGA, "cga" },
+ { GUIO_RENDEREGA, "ega" },
+ { GUIO_RENDERVGA, "vga" },
+ { GUIO_RENDERAMIGA, "amiga" },
+ { GUIO_RENDERFMTOWNS, "fmtowns" },
+ { GUIO_RENDERPC9821, "pc9821" },
+ { GUIO_RENDERPC9801, "pc9801" },
+
+ { GUIO_NONE, 0 }
+};
+
+bool checkGameGUIOption(const String &option, const String &str) {
+ for (int i = 0; g_gameOptions[i].desc; i++) {
+ if (option.contains(g_gameOptions[i].option)) {
+ if (str.contains(g_gameOptions[i].desc))
+ return true;
+ else
+ return false;
+ }
+ }
+ return false;
+}
+
+String parseGameGUIOptions(const String &str) {
+ String res;
+
+ for (int i = 0; g_gameOptions[i].desc; i++)
+ if (str.contains(g_gameOptions[i].desc))
+ res += g_gameOptions[i].option;
+
+ return res;
+}
+
+const String getGameGUIOptionsDescription(const String &options) {
+ String res;
+
+ for (int i = 0; g_gameOptions[i].desc; i++)
+ if (options.contains(g_gameOptions[i].option[0]))
+ res += String(g_gameOptions[i].desc) + " ";
+
+ res.trim();
+
+ return res;
+}
+
+void updateGameGUIOptions(const String &options, const String &langOption) {
+ const String newOptionString = getGameGUIOptionsDescription(options) + " " + langOption;
+
+ if ((!options.empty() && !ConfMan.hasKey("guioptions")) ||
+ (ConfMan.hasKey("guioptions") && ConfMan.get("guioptions") != newOptionString)) {
+ ConfMan.set("guioptions", newOptionString);
+ ConfMan.flushToDisk();
+ }
+}
+
+
+} // End of namespace Common
diff --git a/common/gui_options.h b/common/gui_options.h
new file mode 100644
index 0000000000..33ecccad63
--- /dev/null
+++ b/common/gui_options.h
@@ -0,0 +1,85 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef COMMON_GUI_OPTIONS_H
+#define COMMON_GUI_OPTIONS_H
+
+#define GUIO_NONE "\000"
+#define GUIO_NOSUBTITLES "\001"
+#define GUIO_NOMUSIC "\002"
+#define GUIO_NOSPEECH "\003"
+#define GUIO_NOSFX "\004"
+#define GUIO_NOMIDI "\005"
+#define GUIO_NOLAUNCHLOAD "\006"
+
+#define GUIO_MIDIPCSPK "\007"
+#define GUIO_MIDICMS "\010"
+#define GUIO_MIDIPCJR "\011"
+#define GUIO_MIDIADLIB "\012"
+#define GUIO_MIDIC64 "\013"
+#define GUIO_MIDIAMIGA "\014"
+#define GUIO_MIDIAPPLEIIGS "\015"
+#define GUIO_MIDITOWNS "\016"
+#define GUIO_MIDIPC98 "\017"
+#define GUIO_MIDIMT32 "\020"
+#define GUIO_MIDIGM "\021"
+
+#define GUIO_NOASPECT "\022"
+#define GUIO_EGAUNDITHER "\023"
+
+#define GUIO_RENDERHERCGREEN "\030"
+#define GUIO_RENDERHERCAMBER "\031"
+#define GUIO_RENDERCGA "\032"
+#define GUIO_RENDEREGA "\033"
+#define GUIO_RENDERVGA "\034"
+#define GUIO_RENDERAMIGA "\035"
+#define GUIO_RENDERFMTOWNS "\036"
+#define GUIO_RENDERPC9821 "\037"
+#define GUIO_RENDERPC9801 "\040"
+
+#define GUIO0() (GUIO_NONE)
+#define GUIO1(a) (a)
+#define GUIO2(a,b) (a b)
+#define GUIO3(a,b,c) (a b c)
+#define GUIO4(a,b,c,d) (a b c d)
+#define GUIO5(a,b,c,d,e) (a b c d e)
+#define GUIO6(a,b,c,d,e,f) (a b c d e f)
+
+namespace Common {
+
+class String;
+
+bool checkGameGUIOption(const String &option, const String &str);
+String parseGameGUIOptions(const String &str);
+const String getGameGUIOptionsDescription(const String &options);
+
+/**
+ * Updates the GUI options of the current config manager
+ * domain, when they differ to the ones passed as
+ * parameter.
+ */
+void updateGameGUIOptions(const String &options, const String &langOption);
+
+
+} // End of namespace Common
+
+#endif
diff --git a/common/hash-str.h b/common/hash-str.h
index 1b8a57827a..08f0558bfd 100644
--- a/common/hash-str.h
+++ b/common/hash-str.h
@@ -60,14 +60,14 @@ struct IgnoreCase_Hash {
// case insensitve hashing, then only because one wants to use
// IgnoreCase_EqualTo, and then one has to specify a custom
// hash anyway.
-template <>
+template<>
struct Hash<String> {
uint operator()(const String& s) const {
return hashit(s.c_str());
}
};
-template <>
+template<>
struct Hash<const char *> {
uint operator()(const char *s) const {
return hashit(s);
diff --git a/common/hashmap.h b/common/hashmap.h
index 347ac1fd25..7cf54997e8 100644
--- a/common/hashmap.h
+++ b/common/hashmap.h
@@ -67,7 +67,7 @@ template<class T> class IteratorImpl;
/**
* HashMap<Key,Val> maps objects of type Key to objects of type Val.
- * For each used Key type, we need an "uint hashit(Key,uint)" function
+ * For each used Key type, we need an "size_type hashit(Key,size_type)" function
* that computes a hash for the given Key object and returns it as an
* an integer from 0 to hashsize-1, and also an "equality functor".
* that returns true if if its two arguments are to be considered
@@ -80,6 +80,9 @@ template<class T> class IteratorImpl;
*/
template<class Key, class Val, class HashFunc = Hash<Key>, class EqualFunc = EqualTo<Key> >
class HashMap {
+public:
+ typedef uint size_type;
+
private:
typedef HashMap<Key, Val, HashFunc, EqualFunc> HM_t;
@@ -111,9 +114,9 @@ private:
#endif
Node **_storage; ///< hashtable of size arrsize.
- uint _mask; ///< Capacity of the HashMap minus one; must be a power of two of minus one
- uint _size;
- uint _deleted; ///< Number of deleted elements (_dummyNodes)
+ size_type _mask; ///< Capacity of the HashMap minus one; must be a power of two of minus one
+ size_type _size;
+ size_type _deleted; ///< Number of deleted elements (_dummyNodes)
HashFunc _hash;
EqualFunc _equal;
@@ -146,9 +149,9 @@ private:
}
void assign(const HM_t &map);
- uint lookup(const Key &key) const;
- uint lookupAndCreateIfMissing(const Key &key);
- void expandStorage(uint newCapacity);
+ size_type lookup(const Key &key) const;
+ size_type lookupAndCreateIfMissing(const Key &key);
+ void expandStorage(size_type newCapacity);
#if !defined(__sgi) || defined(__GNUC__)
template<class T> friend class IteratorImpl;
@@ -168,11 +171,11 @@ private:
protected:
typedef const HashMap hashmap_t;
- uint _idx;
+ size_type _idx;
hashmap_t *_hashmap;
protected:
- IteratorImpl(uint idx, hashmap_t *hashmap) : _idx(idx), _hashmap(hashmap) {}
+ IteratorImpl(size_type idx, hashmap_t *hashmap) : _idx(idx), _hashmap(hashmap) {}
NodeType *deref() const {
assert(_hashmap != 0);
@@ -200,7 +203,7 @@ private:
_idx++;
} while (_idx <= _hashmap->_mask && (_hashmap->_storage[_idx] == 0 || _hashmap->_storage[_idx] == HASHMAP_DUMMY_NODE));
if (_idx > _hashmap->_mask)
- _idx = (uint)-1;
+ _idx = (size_type)-1;
return *this;
}
@@ -247,41 +250,41 @@ public:
void erase(iterator entry);
void erase(const Key &key);
- uint size() const { return _size; }
+ size_type size() const { return _size; }
iterator begin() {
// Find and return the first non-empty entry
- for (uint ctr = 0; ctr <= _mask; ++ctr) {
+ for (size_type ctr = 0; ctr <= _mask; ++ctr) {
if (_storage[ctr] && _storage[ctr] != HASHMAP_DUMMY_NODE)
return iterator(ctr, this);
}
return end();
}
iterator end() {
- return iterator((uint)-1, this);
+ return iterator((size_type)-1, this);
}
const_iterator begin() const {
// Find and return the first non-empty entry
- for (uint ctr = 0; ctr <= _mask; ++ctr) {
+ for (size_type ctr = 0; ctr <= _mask; ++ctr) {
if (_storage[ctr] && _storage[ctr] != HASHMAP_DUMMY_NODE)
return const_iterator(ctr, this);
}
return end();
}
const_iterator end() const {
- return const_iterator((uint)-1, this);
+ return const_iterator((size_type)-1, this);
}
iterator find(const Key &key) {
- uint ctr = lookup(key);
+ size_type ctr = lookup(key);
if (_storage[ctr])
return iterator(ctr, this);
return end();
}
const_iterator find(const Key &key) const {
- uint ctr = lookup(key);
+ size_type ctr = lookup(key);
if (_storage[ctr])
return const_iterator(ctr, this);
return end();
@@ -346,7 +349,7 @@ HashMap<Key, Val, HashFunc, EqualFunc>::HashMap(const HM_t &map) :
*/
template<class Key, class Val, class HashFunc, class EqualFunc>
HashMap<Key, Val, HashFunc, EqualFunc>::~HashMap() {
- for (uint ctr = 0; ctr <= _mask; ++ctr)
+ for (size_type ctr = 0; ctr <= _mask; ++ctr)
freeNode(_storage[ctr]);
delete[] _storage;
@@ -373,7 +376,7 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::assign(const HM_t &map) {
// Simply clone the map given to us, one by one.
_size = 0;
_deleted = 0;
- for (uint ctr = 0; ctr <= _mask; ++ctr) {
+ for (size_type ctr = 0; ctr <= _mask; ++ctr) {
if (map._storage[ctr] == HASHMAP_DUMMY_NODE) {
_storage[ctr] = HASHMAP_DUMMY_NODE;
_deleted++;
@@ -391,7 +394,7 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::assign(const HM_t &map) {
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::clear(bool shrinkArray) {
- for (uint ctr = 0; ctr <= _mask; ++ctr) {
+ for (size_type ctr = 0; ctr <= _mask; ++ctr) {
freeNode(_storage[ctr]);
_storage[ctr] = NULL;
}
@@ -414,13 +417,13 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::clear(bool shrinkArray) {
}
template<class Key, class Val, class HashFunc, class EqualFunc>
-void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(uint newCapacity) {
+void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(size_type newCapacity) {
assert(newCapacity > _mask+1);
#ifndef NDEBUG
- const uint old_size = _size;
+ const size_type old_size = _size;
#endif
- const uint old_mask = _mask;
+ const size_type old_mask = _mask;
Node **old_storage = _storage;
// allocate a new array
@@ -432,7 +435,7 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(uint newCapacity) {
memset(_storage, 0, newCapacity * sizeof(Node *));
// rehash all the old elements
- for (uint ctr = 0; ctr <= old_mask; ++ctr) {
+ for (size_type ctr = 0; ctr <= old_mask; ++ctr) {
if (old_storage[ctr] == NULL || old_storage[ctr] == HASHMAP_DUMMY_NODE)
continue;
@@ -440,9 +443,9 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(uint newCapacity) {
// Since we know that no key exists twice in the old table, we
// can do this slightly better than by calling lookup, since we
// don't have to call _equal().
- const uint hash = _hash(old_storage[ctr]->_key);
- uint idx = hash & _mask;
- for (uint perturb = hash; _storage[idx] != NULL && _storage[idx] != HASHMAP_DUMMY_NODE; perturb >>= HASHMAP_PERTURB_SHIFT) {
+ const size_type hash = _hash(old_storage[ctr]->_key);
+ size_type idx = hash & _mask;
+ for (size_type perturb = hash; _storage[idx] != NULL && _storage[idx] != HASHMAP_DUMMY_NODE; perturb >>= HASHMAP_PERTURB_SHIFT) {
idx = (5 * idx + perturb + 1) & _mask;
}
@@ -460,10 +463,10 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(uint newCapacity) {
}
template<class Key, class Val, class HashFunc, class EqualFunc>
-uint HashMap<Key, Val, HashFunc, EqualFunc>::lookup(const Key &key) const {
- const uint hash = _hash(key);
- uint ctr = hash & _mask;
- for (uint perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
+typename HashMap<Key, Val, HashFunc, EqualFunc>::size_type HashMap<Key, Val, HashFunc, EqualFunc>::lookup(const Key &key) const {
+ const size_type hash = _hash(key);
+ size_type ctr = hash & _mask;
+ for (size_type perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
if (_storage[ctr] == NULL)
break;
if (_storage[ctr] == HASHMAP_DUMMY_NODE) {
@@ -491,13 +494,13 @@ uint HashMap<Key, Val, HashFunc, EqualFunc>::lookup(const Key &key) const {
}
template<class Key, class Val, class HashFunc, class EqualFunc>
-uint HashMap<Key, Val, HashFunc, EqualFunc>::lookupAndCreateIfMissing(const Key &key) {
- const uint hash = _hash(key);
- uint ctr = hash & _mask;
- const uint NONE_FOUND = _mask + 1;
- uint first_free = NONE_FOUND;
+typename HashMap<Key, Val, HashFunc, EqualFunc>::size_type HashMap<Key, Val, HashFunc, EqualFunc>::lookupAndCreateIfMissing(const Key &key) {
+ const size_type hash = _hash(key);
+ size_type ctr = hash & _mask;
+ const size_type NONE_FOUND = _mask + 1;
+ size_type first_free = NONE_FOUND;
bool found = false;
- for (uint perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
+ for (size_type perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
if (_storage[ctr] == NULL)
break;
if (_storage[ctr] == HASHMAP_DUMMY_NODE) {
@@ -537,7 +540,7 @@ uint HashMap<Key, Val, HashFunc, EqualFunc>::lookupAndCreateIfMissing(const Key
// Keep the load factor below a certain threshold.
// Deleted nodes are also counted
- uint capacity = _mask + 1;
+ size_type capacity = _mask + 1;
if ((_size + _deleted) * HASHMAP_LOADFACTOR_DENOMINATOR >
capacity * HASHMAP_LOADFACTOR_NUMERATOR) {
capacity = capacity < 500 ? (capacity * 4) : (capacity * 2);
@@ -553,7 +556,7 @@ uint HashMap<Key, Val, HashFunc, EqualFunc>::lookupAndCreateIfMissing(const Key
template<class Key, class Val, class HashFunc, class EqualFunc>
bool HashMap<Key, Val, HashFunc, EqualFunc>::contains(const Key &key) const {
- uint ctr = lookup(key);
+ size_type ctr = lookup(key);
return (_storage[ctr] != NULL);
}
@@ -569,7 +572,7 @@ const Val &HashMap<Key, Val, HashFunc, EqualFunc>::operator[](const Key &key) co
template<class Key, class Val, class HashFunc, class EqualFunc>
Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) {
- uint ctr = lookupAndCreateIfMissing(key);
+ size_type ctr = lookupAndCreateIfMissing(key);
assert(_storage[ctr] != NULL);
return _storage[ctr]->_value;
}
@@ -581,7 +584,7 @@ const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) const
template<class Key, class Val, class HashFunc, class EqualFunc>
const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key, const Val &defaultVal) const {
- uint ctr = lookup(key);
+ size_type ctr = lookup(key);
if (_storage[ctr] != NULL)
return _storage[ctr]->_value;
else
@@ -590,7 +593,7 @@ const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key, const
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::setVal(const Key &key, const Val &val) {
- uint ctr = lookupAndCreateIfMissing(key);
+ size_type ctr = lookupAndCreateIfMissing(key);
assert(_storage[ctr] != NULL);
_storage[ctr]->_value = val;
}
@@ -599,7 +602,7 @@ template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::erase(iterator entry) {
// Check whether we have a valid iterator
assert(entry._hashmap == this);
- const uint ctr = entry._idx;
+ const size_type ctr = entry._idx;
assert(ctr <= _mask);
Node * const node = _storage[ctr];
assert(node != NULL);
@@ -615,7 +618,7 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::erase(iterator entry) {
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::erase(const Key &key) {
- uint ctr = lookup(key);
+ size_type ctr = lookup(key);
if (_storage[ctr] == NULL)
return;
diff --git a/common/huffman.h b/common/huffman.h
index 4175d0d309..3b23340b2e 100644
--- a/common/huffman.h
+++ b/common/huffman.h
@@ -68,7 +68,7 @@ private:
typedef List<Symbol> CodeList;
typedef Array<CodeList> CodeLists;
- typedef Array<Symbol*> SymbolList;
+ typedef Array<Symbol *> SymbolList;
/** Lists of codes and their symbols, sorted by code length. */
CodeLists _codes;
diff --git a/common/keyboard.h b/common/keyboard.h
index ead6ed427b..e6db086598 100644
--- a/common/keyboard.h
+++ b/common/keyboard.h
@@ -224,11 +224,14 @@ enum {
KBD_CTRL = 1 << 0,
KBD_ALT = 1 << 1,
KBD_SHIFT = 1 << 2,
+ KBD_NON_STICKY = (KBD_CTRL|KBD_ALT|KBD_SHIFT),
// Sticky modifier flags
KBD_NUM = 1 << 3,
KBD_CAPS = 1 << 4,
- KBD_SCRL = 1 << 5
+ KBD_SCRL = 1 << 5,
+ KBD_STICKY = (KBD_NUM|KBD_CAPS|KBD_SCRL)
+
};
/**
@@ -281,19 +284,27 @@ struct KeyState {
/**
* Check whether the non-sticky flags are *exactly* as specified by f.
- * This ignors the sticky flags (KBD_NUM, KBD_CAPS, KBD_SCRL).
+ * This ignores the sticky flags (KBD_NUM, KBD_CAPS, KBD_SCRL).
+ * Sticky flags should never be passed to this function.
* If you just want to check whether a modifier flag is set, just bit-and
* the flag. E.g. to check whether the control key modifier is set,
* you can write
* if (keystate.flags & KBD_CTRL) { ... }
*/
bool hasFlags(byte f) const {
- return f == (flags & ~(KBD_NUM|KBD_CAPS|KBD_SCRL));
+ assert(!(f & KBD_STICKY));
+ return f == (flags & ~KBD_STICKY);
}
+ /**
+ * Check if two key states are equal. This implementation ignores the state
+ * of the sticky flags (caps lock, num lock, scroll lock) completely. This
+ * functionality is currently only used by the keymapper.
+ */
bool operator==(const KeyState &x) const {
- // intentionally ignore ascii
- return keycode == x.keycode && flags == x.flags;
+ // Intentionally ignore ASCII, as the keycode and non-sticky flag
+ // combination should suffice.
+ return keycode == x.keycode && hasFlags(x.flags & ~KBD_STICKY);
}
};
diff --git a/common/language.cpp b/common/language.cpp
new file mode 100644
index 0000000000..898adf8d0e
--- /dev/null
+++ b/common/language.cpp
@@ -0,0 +1,125 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "common/language.h"
+#include "common/gui_options.h"
+#include "common/str.h"
+
+namespace Common {
+
+const LanguageDescription g_languages[] = {
+ { "zh-cn", "zh_CN", "Chinese (China)", ZH_CNA },
+ { "zh", "zh_TW", "Chinese (Taiwan)", ZH_TWN },
+ { "cz", "cs_CZ", "Czech", CZ_CZE },
+ { "nl", "nl_NL", "Dutch", NL_NLD },
+ { "en", "en", "English", EN_ANY }, // Generic English (when only one game version exist)
+ { "gb", "en_GB", "English (GB)", EN_GRB },
+ { "us", "en_US", "English (US)", EN_USA },
+ { "fr", "fr_FR", "French", FR_FRA },
+ { "de", "de_DE", "German", DE_DEU },
+ { "gr", "el_GR", "Greek", GR_GRE },
+ { "he", "he_IL", "Hebrew", HE_ISR },
+ { "hb", "he_IL", "Hebrew", HE_ISR }, // Deprecated
+ { "hr", "hr_HR", "Croatian", HR_HRV },
+ { "hu", "hu_HU", "Hungarian", HU_HUN },
+ { "it", "it_IT", "Italian", IT_ITA },
+ { "jp", "ja_JP", "Japanese", JA_JPN },
+ { "kr", "ko_KR", "Korean", KO_KOR },
+ { "nb", "nb_NO", "Norwegian Bokm\xE5l", NB_NOR }, // TODO Someone should verify the unix locale
+ { "pl", "pl_PL", "Polish", PL_POL },
+ { "br", "pt_BR", "Portuguese", PT_BRA },
+ { "ru", "ru_RU", "Russian", RU_RUS },
+ { "es", "es_ES", "Spanish", ES_ESP },
+ { "se", "sv_SE", "Swedish", SE_SWE },
+ { 0, 0, 0, UNK_LANG }
+};
+
+Language parseLanguage(const String &str) {
+ if (str.empty())
+ return UNK_LANG;
+
+ const LanguageDescription *l = g_languages;
+ for (; l->code; ++l) {
+ if (str.equalsIgnoreCase(l->code))
+ return l->id;
+ }
+
+ return UNK_LANG;
+}
+
+Language parseLanguageFromLocale(const char *locale) {
+ if (!locale || !*locale)
+ return UNK_LANG;
+
+ const LanguageDescription *l = g_languages;
+ for (; l->code; ++l) {
+ if (!strcmp(l->unixLocale, locale))
+ return l->id;
+ }
+
+ return UNK_LANG;
+}
+
+const char *getLanguageCode(Language id) {
+ const LanguageDescription *l = g_languages;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->code;
+ }
+ return 0;
+}
+
+const char *getLanguageLocale(Language id) {
+ const LanguageDescription *l = g_languages;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->unixLocale;
+ }
+ return 0;
+}
+
+const char *getLanguageDescription(Language id) {
+ const LanguageDescription *l = g_languages;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->description;
+ }
+ return 0;
+}
+
+bool checkGameGUIOptionLanguage(Language lang, const String &str) {
+ if (!str.contains("lang_")) // If no languages are specified
+ return true;
+
+ if (str.contains(getGameGUIOptionsDescriptionLanguage(lang)))
+ return true;
+
+ return false;
+}
+
+const String getGameGUIOptionsDescriptionLanguage(Language lang) {
+ if (lang == UNK_LANG)
+ return "";
+
+ return String("lang_") + getLanguageDescription(lang);
+}
+
+} // End of namespace Common
diff --git a/common/language.h b/common/language.h
new file mode 100644
index 0000000000..db552fc9c4
--- /dev/null
+++ b/common/language.h
@@ -0,0 +1,86 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef COMMON_LANGUAGE_H
+#define COMMON_LANGUAGE_H
+
+#include "common/scummsys.h"
+
+namespace Common {
+
+class String;
+
+/**
+ * List of game language.
+ */
+enum Language {
+ ZH_CNA,
+ ZH_TWN,
+ CZ_CZE,
+ NL_NLD,
+ EN_ANY, // Generic English (when only one game version exist)
+ EN_GRB,
+ EN_USA,
+ FR_FRA,
+ DE_DEU,
+ GR_GRE,
+ HE_ISR,
+ HR_HRV,
+ HU_HUN,
+ IT_ITA,
+ JA_JPN,
+ KO_KOR,
+ NB_NOR,
+ PL_POL,
+ PT_BRA,
+ RU_RUS,
+ ES_ESP,
+ SE_SWE,
+
+ UNK_LANG = -1 // Use default language (i.e. none specified)
+};
+
+struct LanguageDescription {
+ const char *code;
+ const char *unixLocale;
+ const char *description;
+ Language id;
+};
+
+extern const LanguageDescription g_languages[];
+
+
+/** Convert a string containing a language name into a Language enum value. */
+extern Language parseLanguage(const String &str);
+extern Language parseLanguageFromLocale(const char *locale);
+extern const char *getLanguageCode(Language id);
+extern const char *getLanguageLocale(Language id);
+extern const char *getLanguageDescription(Language id);
+
+// TODO: Document this GUIO related function
+const String getGameGUIOptionsDescriptionLanguage(Common::Language lang);
+
+// TODO: Document this GUIO related function
+bool checkGameGUIOptionLanguage(Common::Language lang, const String &str);
+
+} // End of namespace Common
+
+#endif
diff --git a/common/list.h b/common/list.h
index a1e761f55d..9792042239 100644
--- a/common/list.h
+++ b/common/list.h
@@ -43,6 +43,7 @@ public:
typedef ListInternal::ConstIterator<t_T> const_iterator;
typedef t_T value_type;
+ typedef uint size_type;
public:
List() {
@@ -181,8 +182,8 @@ public:
return *this;
}
- uint size() const {
- uint n = 0;
+ size_type size() const {
+ size_type n = 0;
for (const NodeBase *cur = _anchor._next; cur != &_anchor; cur = cur->_next)
++n;
return n;
@@ -226,7 +227,7 @@ public:
}
const_iterator end() const {
- return const_iterator(const_cast<NodeBase*>(&_anchor));
+ return const_iterator(const_cast<NodeBase *>(&_anchor));
}
protected:
diff --git a/common/list_intern.h b/common/list_intern.h
index daa7446781..fef32fbe1e 100644
--- a/common/list_intern.h
+++ b/common/list_intern.h
@@ -35,7 +35,7 @@ namespace ListInternal {
NodeBase *_next;
};
- template <typename T>
+ template<typename T>
struct Node : public NodeBase {
T _data;
diff --git a/common/localization.h b/common/localization.h
index 3945cf5fab..e908485b99 100644
--- a/common/localization.h
+++ b/common/localization.h
@@ -22,7 +22,7 @@
#ifndef COMMON_LOCALIZATION_H
#define COMMON_LOCALIZATION_H
-#include "common/util.h"
+#include "common/language.h"
#include "common/keyboard.h"
namespace Common {
diff --git a/common/macresman.cpp b/common/macresman.cpp
index 1317600cb7..14bdfa7080 100644
--- a/common/macresman.cpp
+++ b/common/macresman.cpp
@@ -238,6 +238,27 @@ bool MacResManager::open(FSNode path, String filename) {
return false;
}
+bool MacResManager::exists(const String &filename) {
+ // Try the file name by itself
+ if (Common::File::exists(filename))
+ return true;
+
+ // Try the .rsrc extension
+ if (Common::File::exists(filename + ".rsrc"))
+ return true;
+
+ // Check if we have a MacBinary file
+ Common::File tempFile;
+ if (tempFile.open(filename + ".bin") && isMacBinary(tempFile))
+ return true;
+
+ // Check if we have an AppleDouble file
+ if (tempFile.open("._" + filename) && tempFile.readUint32BE() == 0x00051607)
+ return true;
+
+ return false;
+}
+
bool MacResManager::loadFromAppleDouble(SeekableReadStream &stream) {
if (stream.readUint32BE() != 0x00051607) // tag
return false;
diff --git a/common/macresman.h b/common/macresman.h
index 4d86e46d11..6820106925 100644
--- a/common/macresman.h
+++ b/common/macresman.h
@@ -69,6 +69,13 @@ public:
bool open(FSNode path, String filename);
/**
+ * See if a Mac data/resource fork pair exists.
+ * @param filename The base file name of the file
+ * @return True if either a data fork or resource fork with this name exists
+ */
+ static bool exists(const String &filename);
+
+ /**
* Close the Mac data/resource fork pair.
*/
void close();
diff --git a/common/math.h b/common/math.h
index f787b84fa6..b85ec0d22a 100644
--- a/common/math.h
+++ b/common/math.h
@@ -75,7 +75,7 @@ struct Complex {
float re, im;
};
-#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#if GCC_ATLEAST(3, 4)
inline int intLog2(uint32 v) {
// This is a slightly optimized implementation of log2 for natural numbers
// targeting gcc. It also saves some binary size over our fallback
diff --git a/common/memorypool.cpp b/common/memorypool.cpp
index 19adc54d00..e3742eeae0 100644
--- a/common/memorypool.cpp
+++ b/common/memorypool.cpp
@@ -33,7 +33,7 @@ static size_t adjustChunkSize(size_t chunkSize) {
// You must at least fit the pointer in the node (technically unneeded considering the next rounding statement)
chunkSize = MAX(chunkSize, sizeof(void *));
// There might be an alignment problem on some platforms when trying to load a void* on a non natural boundary
- // so we round to the next sizeof(void*)
+ // so we round to the next sizeof(void *)
chunkSize = (chunkSize + sizeof(void *) - 1) & (~(sizeof(void *) - 1));
return chunkSize;
diff --git a/common/memorypool.h b/common/memorypool.h
index 5ba09cebed..9a4e523d53 100644
--- a/common/memorypool.h
+++ b/common/memorypool.h
@@ -105,7 +105,7 @@ template<size_t CHUNK_SIZE, size_t NUM_INTERNAL_CHUNKS = 32>
class FixedSizeMemoryPool : public MemoryPool {
private:
enum {
- REAL_CHUNK_SIZE = (CHUNK_SIZE + sizeof(void*) - 1) & (~(sizeof(void*) - 1))
+ REAL_CHUNK_SIZE = (CHUNK_SIZE + sizeof(void *) - 1) & (~(sizeof(void *) - 1))
};
byte _storage[NUM_INTERNAL_CHUNKS * REAL_CHUNK_SIZE];
diff --git a/common/module.mk b/common/module.mk
index 7434df7052..b4928fabda 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -8,19 +8,24 @@ MODULE_OBJS := \
debug.o \
error.o \
EventDispatcher.o \
+ EventMapper.o \
EventRecorder.o \
file.o \
fs.o \
+ gui_options.o \
hashmap.o \
iff_container.o \
+ language.o \
localization.o \
macresman.o \
memorypool.o \
md5.o \
mutex.o \
+ platform.o \
quicktime.o \
random.o \
rational.o \
+ rendermode.o \
str.o \
stream.o \
system.o \
diff --git a/common/platform.cpp b/common/platform.cpp
new file mode 100644
index 0000000000..9986048b48
--- /dev/null
+++ b/common/platform.cpp
@@ -0,0 +1,107 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "common/platform.h"
+#include "common/str.h"
+
+namespace Common {
+
+const PlatformDescription g_platforms[] = {
+ { "2gs", "2gs", "2gs", "Apple IIgs", kPlatformApple2GS },
+ { "3do", "3do", "3do", "3DO", kPlatform3DO },
+ { "acorn", "acorn", "acorn", "Acorn", kPlatformAcorn },
+ { "amiga", "ami", "amiga", "Amiga", kPlatformAmiga },
+ { "atari", "atari-st", "st", "Atari ST", kPlatformAtariST },
+ { "c64", "c64", "c64", "Commodore 64", kPlatformC64 },
+ { "pc", "dos", "ibm", "DOS", kPlatformPC },
+ { "pc98", "pc98", "pc98", "PC-98", kPlatformPC98 },
+ { "wii", "wii", "wii", "Nintendo Wii", kPlatformWii },
+ { "coco3", "coco3", "coco3", "CoCo3", kPlatformCoCo3 },
+
+ // The 'official' spelling seems to be "FM-TOWNS" (e.g. in the Indy4 demo).
+ // However, on the net many variations can be seen, like "FMTOWNS",
+ // "FM TOWNS", "FmTowns", etc.
+ { "fmtowns", "towns", "fm", "FM-TOWNS", kPlatformFMTowns },
+
+ { "linux", "linux", "linux", "Linux", kPlatformLinux },
+ { "macintosh", "mac", "mac", "Macintosh", kPlatformMacintosh },
+ { "pce", "pce", "pce", "PC-Engine", kPlatformPCEngine },
+ { "nes", "nes", "nes", "NES", kPlatformNES },
+ { "segacd", "segacd", "sega", "SegaCD", kPlatformSegaCD },
+ { "windows", "win", "win", "Windows", kPlatformWindows },
+ { "playstation", "psx", "psx", "Sony PlayStation", kPlatformPSX },
+ { "cdi", "cdi", "cdi", "Philips CD-i", kPlatformCDi },
+ { "ios", "ios", "ios", "Apple iOS", kPlatformIOS },
+
+ { 0, 0, 0, "Default", kPlatformUnknown }
+};
+
+Platform parsePlatform(const String &str) {
+ if (str.empty())
+ return kPlatformUnknown;
+
+ // Handle some special case separately, for compatibility with old config
+ // files.
+ if (str == "1")
+ return kPlatformAmiga;
+ else if (str == "2")
+ return kPlatformAtariST;
+ else if (str == "3")
+ return kPlatformMacintosh;
+
+ const PlatformDescription *l = g_platforms;
+ for (; l->code; ++l) {
+ if (str.equalsIgnoreCase(l->code) || str.equalsIgnoreCase(l->code2) || str.equalsIgnoreCase(l->abbrev))
+ return l->id;
+ }
+
+ return kPlatformUnknown;
+}
+
+
+const char *getPlatformCode(Platform id) {
+ const PlatformDescription *l = g_platforms;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->code;
+ }
+ return 0;
+}
+
+const char *getPlatformAbbrev(Platform id) {
+ const PlatformDescription *l = g_platforms;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->abbrev;
+ }
+ return 0;
+}
+
+const char *getPlatformDescription(Platform id) {
+ const PlatformDescription *l = g_platforms;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->description;
+ }
+ return l->description;
+}
+
+} // End of namespace Common
diff --git a/common/platform.h b/common/platform.h
new file mode 100644
index 0000000000..1891c7096d
--- /dev/null
+++ b/common/platform.h
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef COMMON_PLATFORM_H
+#define COMMON_PLATFORM_H
+
+#include "common/scummsys.h"
+
+namespace Common {
+
+class String;
+
+/**
+ * List of game platforms. Specifying a platform for a target can be used to
+ * give the game engines a hint for which platform the game data file are.
+ * This may be optional or required, depending on the game engine and the
+ * game in question.
+ */
+enum Platform {
+ kPlatformPC,
+ kPlatformAmiga,
+ kPlatformAtariST,
+ kPlatformMacintosh,
+ kPlatformFMTowns,
+ kPlatformWindows,
+ kPlatformNES,
+ kPlatformC64,
+ kPlatformCoCo3,
+ kPlatformLinux,
+ kPlatformAcorn,
+ kPlatformSegaCD,
+ kPlatform3DO,
+ kPlatformPCEngine,
+ kPlatformApple2GS,
+ kPlatformPC98,
+ kPlatformWii,
+ kPlatformPSX,
+ kPlatformCDi,
+ kPlatformIOS,
+
+ kPlatformUnknown = -1
+};
+
+struct PlatformDescription {
+ const char *code;
+ const char *code2;
+ const char *abbrev;
+ const char *description;
+ Platform id;
+};
+
+extern const PlatformDescription g_platforms[];
+
+/** Convert a string containing a platform name into a Platform enum value. */
+extern Platform parsePlatform(const String &str);
+extern const char *getPlatformCode(Platform id);
+extern const char *getPlatformAbbrev(Platform id);
+extern const char *getPlatformDescription(Platform id);
+
+} // End of namespace Common
+
+#endif
diff --git a/common/ptr.h b/common/ptr.h
index 2b0670caae..f734ec133f 100644
--- a/common/ptr.h
+++ b/common/ptr.h
@@ -103,7 +103,7 @@ private:
*/
template<class T>
class SharedPtr {
-#if !((__GNUC__ == 2) && (__GNUC_MINOR__ >= 95))
+#if !defined(__GNUC__) || GCC_ATLEAST(3, 0)
template<class T2> friend class SharedPtr;
#endif
public:
@@ -200,7 +200,7 @@ public:
* This should just be used for debugging purposes.
*/
RefValue refCount() const { return _refCount ? *_refCount : 0; }
-#if !((__GNUC__ == 2) && (__GNUC_MINOR__ >= 95))
+#if !defined(__GNUC__) || GCC_ATLEAST(3, 0)
private:
#endif
void decRef() {
diff --git a/common/quicktime.cpp b/common/quicktime.cpp
index e16d3f2652..fb01e8de28 100644
--- a/common/quicktime.cpp
+++ b/common/quicktime.cpp
@@ -66,7 +66,7 @@ bool QuickTimeParser::parseFile(const String &filename) {
_foundMOOV = false;
_disposeFileHandle = DisposeAfterUse::YES;
- Atom atom = { 0, 0, 0xffffffff };
+ Atom atom = { 0, 0, 0 };
if (_resFork->hasResFork()) {
// Search for a 'moov' resource
@@ -80,14 +80,12 @@ bool QuickTimeParser::parseFile(const String &filename) {
if (readDefault(atom) < 0 || !_foundMOOV)
return false;
}
- delete _fd;
- atom.type = 0;
- atom.offset = 0;
- atom.size = 0xffffffff;
+ delete _fd;
}
_fd = _resFork->getDataFork();
+ atom.size = _fd->size();
if (readDefault(atom) < 0 || !_foundMOOV)
return false;
@@ -113,19 +111,29 @@ bool QuickTimeParser::parseStream(SeekableReadStream *stream, DisposeAfterUse::F
}
void QuickTimeParser::init() {
- // Remove unknown/unhandled tracks
for (uint32 i = 0; i < _tracks.size(); i++) {
+ // Remove unknown/unhandled tracks
if (_tracks[i]->codecType == CODEC_TYPE_MOV_OTHER) {
delete _tracks[i];
_tracks.remove_at(i);
i--;
+ } else {
+ // If this track doesn't have a declared scale, use the movie scale
+ if (_tracks[i]->timeScale == 0)
+ _tracks[i]->timeScale = _timeScale;
+
+ // If this track doesn't have an edit list (like in MPEG-4 files),
+ // fake an entry of one edit that takes up the entire sample
+ if (_tracks[i]->editCount == 0) {
+ _tracks[i]->editCount = 1;
+ _tracks[i]->editList = new EditListEntry[1];
+ _tracks[i]->editList[0].trackDuration = _tracks[i]->duration;
+ _tracks[i]->editList[0].timeOffset = 0;
+ _tracks[i]->editList[0].mediaTime = 0;
+ _tracks[i]->editList[0].mediaRate = 1;
+ }
}
}
-
- // Adjust time scale
- for (uint32 i = 0; i < _tracks.size(); i++)
- if (!_tracks[i]->timeScale)
- _tracks[i]->timeScale = _timeScale;
}
void QuickTimeParser::initParseTable() {
@@ -135,7 +143,7 @@ void QuickTimeParser::initParseTable() {
{ &QuickTimeParser::readDefault, MKTAG('e', 'd', 't', 's') },
{ &QuickTimeParser::readELST, MKTAG('e', 'l', 's', 't') },
{ &QuickTimeParser::readHDLR, MKTAG('h', 'd', 'l', 'r') },
- { &QuickTimeParser::readDefault, MKTAG('m', 'd', 'a', 't') },
+ { &QuickTimeParser::readLeaf, MKTAG('m', 'd', 'a', 't') },
{ &QuickTimeParser::readMDHD, MKTAG('m', 'd', 'h', 'd') },
{ &QuickTimeParser::readDefault, MKTAG('m', 'd', 'i', 'a') },
{ &QuickTimeParser::readDefault, MKTAG('m', 'i', 'n', 'f') },
diff --git a/common/quicktime.h b/common/quicktime.h
index d7e2691c2b..efd2adbd21 100644
--- a/common/quicktime.h
+++ b/common/quicktime.h
@@ -155,7 +155,7 @@ protected:
uint16 height;
CodecType codecType;
- Array<SampleDesc*> sampleDescs;
+ Array<SampleDesc *> sampleDescs;
uint32 editCount;
EditListEntry *editList;
@@ -180,7 +180,7 @@ protected:
uint32 _duration;
Rational _scaleFactorX;
Rational _scaleFactorY;
- Array<Track*> _tracks;
+ Array<Track *> _tracks;
uint32 _beginOffset;
MacResManager *_resFork;
diff --git a/common/rect.h b/common/rect.h
index 1106ec1714..e48ca53667 100644
--- a/common/rect.h
+++ b/common/rect.h
@@ -258,11 +258,12 @@ struct Rect {
/**
* Create a rectangle around the given center.
+ * @note the center point is rounded up and left when given an odd width and height
*/
static Rect center(int16 cx, int16 cy, int16 w, int16 h) {
- w /= 2;
- h /= 2;
- return Rect(cx - w, cy - h, cx + w, cy + h);
+ int dx = w / 2;
+ int dy = h / 2;
+ return Rect(cx - dx, cy - dy, cx + dx + (w & 1), cy + dy + (h & 1));
}
};
diff --git a/common/rendermode.cpp b/common/rendermode.cpp
new file mode 100644
index 0000000000..e8f3146630
--- /dev/null
+++ b/common/rendermode.cpp
@@ -0,0 +1,122 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/rendermode.h"
+
+#include "common/gui_options.h"
+#include "common/str.h"
+#include "common/translation.h"
+
+
+namespace Common {
+
+
+const RenderModeDescription g_renderModes[] = {
+ // I18N: Hercules is graphics card name
+ { "hercGreen", _s("Hercules Green"), kRenderHercG },
+ { "hercAmber", _s("Hercules Amber"), kRenderHercA },
+ { "cga", "CGA", kRenderCGA },
+ { "ega", "EGA", kRenderEGA },
+ { "vga", "VGA", kRenderVGA },
+ { "amiga", "Amiga", kRenderAmiga },
+ { "fmtowns", "FM-Towns", kRenderFMTowns },
+ { "pc9821", "PC-9821 (256 Colors)", kRenderPC9821 },
+ { "pc9801", "PC-9801 (16 Colors)", kRenderPC9801 },
+ {0, 0, kRenderDefault}
+};
+
+struct RenderGUIOMapping {
+ RenderMode id;
+ const char *guio;
+};
+
+// TODO: Merge s_renderGUIOMapping into g_renderModes? the kRenderDefault
+// could be used to indicate "any" mode when passed to renderMode2GUIO (if
+// we wanted to merge allRenderModesGUIOs back into)
+static const RenderGUIOMapping s_renderGUIOMapping[] = {
+ { kRenderHercG, GUIO_RENDERHERCGREEN },
+ { kRenderHercA, GUIO_RENDERHERCAMBER },
+ { kRenderCGA, GUIO_RENDERCGA },
+ { kRenderEGA, GUIO_RENDEREGA },
+ { kRenderVGA, GUIO_RENDERVGA },
+ { kRenderAmiga, GUIO_RENDERAMIGA },
+ { kRenderFMTowns, GUIO_RENDERFMTOWNS },
+ { kRenderPC9821, GUIO_RENDERPC9821 },
+ { kRenderPC9801, GUIO_RENDERPC9801 }
+};
+
+DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Hercules Green", "lowres")
+DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Hercules Amber", "lowres")
+
+RenderMode parseRenderMode(const String &str) {
+ if (str.empty())
+ return kRenderDefault;
+
+ const RenderModeDescription *l = g_renderModes;
+ for (; l->code; ++l) {
+ if (str.equalsIgnoreCase(l->code))
+ return l->id;
+ }
+
+ return kRenderDefault;
+}
+
+const char *getRenderModeCode(RenderMode id) {
+ const RenderModeDescription *l = g_renderModes;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->code;
+ }
+ return 0;
+}
+
+const char *getRenderModeDescription(RenderMode id) {
+ const RenderModeDescription *l = g_renderModes;
+ for (; l->code; ++l) {
+ if (l->id == id)
+ return l->description;
+ }
+ return 0;
+}
+
+String renderMode2GUIO(RenderMode id) {
+ String res;
+
+ for (int i = 0; i < ARRAYSIZE(s_renderGUIOMapping); i++) {
+ if (id == s_renderGUIOMapping[i].id)
+ res += s_renderGUIOMapping[i].guio;
+ }
+
+ return res;
+}
+
+String allRenderModesGUIOs() {
+ String res;
+
+ for (int i = 0; i < ARRAYSIZE(s_renderGUIOMapping); i++) {
+ res += s_renderGUIOMapping[i].guio;
+ }
+
+ return res;
+}
+
+} // End of namespace Common
diff --git a/common/rendermode.h b/common/rendermode.h
new file mode 100644
index 0000000000..945c4e7d9d
--- /dev/null
+++ b/common/rendermode.h
@@ -0,0 +1,73 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef COMMON_RENDERMODE_H
+#define COMMON_RENDERMODE_H
+
+#include "common/scummsys.h"
+
+namespace Common {
+
+class String;
+
+/**
+ * List of render modes. It specifies which original graphics mode
+ * to use. Some targets used postprocessing dithering routines for
+ * reducing color depth of final image which let it to be rendered on
+ * such low-level adapters as CGA or Hercules.
+ */
+enum RenderMode {
+ kRenderDefault = 0,
+ kRenderVGA = 1,
+ kRenderEGA = 2,
+ kRenderCGA = 3,
+ kRenderHercG = 4,
+ kRenderHercA = 5,
+ kRenderAmiga = 6,
+ kRenderFMTowns = 7,
+ kRenderPC9821 = 8,
+ kRenderPC9801 = 9
+};
+
+struct RenderModeDescription {
+ const char *code;
+ const char *description;
+ RenderMode id;
+};
+
+extern const RenderModeDescription g_renderModes[];
+
+/** Convert a string containing a render mode name into a RenderingMode enum value. */
+extern RenderMode parseRenderMode(const String &str);
+extern const char *getRenderModeCode(RenderMode id);
+extern const char *getRenderModeDescription(RenderMode id);
+
+// TODO: Rename the following to something better; also, document it
+extern String renderMode2GUIO(RenderMode id);
+
+// TODO: Rename the following to something better; also, document it
+extern String allRenderModesGUIOs();
+
+
+} // End of namespace Common
+
+#endif
diff --git a/common/scummsys.h b/common/scummsys.h
index 6baab7c16f..2f4efe702f 100644
--- a/common/scummsys.h
+++ b/common/scummsys.h
@@ -23,6 +23,9 @@
#ifndef COMMON_SCUMMSYS_H
#define COMMON_SCUMMSYS_H
+// This is a convenience macro to test whether the compiler used is a GCC
+// version, which is at least major.minor.
+#define GCC_ATLEAST(major, minor) (defined(__GNUC__) && (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
#if defined(_WIN32_WCE) && _WIN32_WCE < 300
#define NONSTANDARD_PORT
@@ -268,7 +271,7 @@
#ifndef FORCEINLINE
#if defined(_MSC_VER)
#define FORCEINLINE __forceinline
- #elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+ #elif GCC_ATLEAST(3, 1)
#define FORCEINLINE inline __attribute__((__always_inline__))
#else
#define FORCEINLINE inline
@@ -316,7 +319,7 @@
#define scumm_va_copy va_copy
#elif defined(__va_copy)
#define scumm_va_copy __va_copy
- #elif defined(_MSC_VER) || defined (__SYMBIAN32__)
+ #elif defined(_MSC_VER) || defined(__SYMBIAN32__)
#define scumm_va_copy(dst, src) ((dst) = (src))
#else
#error scumm_va_copy undefined for this port
diff --git a/common/serializer.h b/common/serializer.h
index 5b08a9a9fa..4d97c9e930 100644
--- a/common/serializer.h
+++ b/common/serializer.h
@@ -30,7 +30,7 @@ namespace Common {
#define SYNC_AS(SUFFIX,TYPE,SIZE) \
- template <typename T> \
+ template<typename T> \
void syncAs ## SUFFIX(T &val, Version minVersion = 0, Version maxVersion = kLastVersion) { \
if (_version < minVersion || _version > maxVersion) \
return; \
diff --git a/common/singleton.h b/common/singleton.h
index 43f1c0c4d0..d7078360f3 100644
--- a/common/singleton.h
+++ b/common/singleton.h
@@ -43,8 +43,8 @@ private:
* singleton class might be pure virtual (or "abstract" in Java terminology),
* and you specialise makeInstance to return an instance of a subclass.
*/
- //template <class T>
-#if defined (_WIN32_WCE) || defined (_MSC_VER) || defined (__WINS__)
+ //template<class T>
+#if defined(_WIN32_WCE) || defined(_MSC_VER) || defined(__WINS__)
//FIXME evc4 and msvc7 doesn't like it as private member
public:
#endif
diff --git a/common/stack.h b/common/stack.h
index 0d13049f2e..bc5de9ac7f 100644
--- a/common/stack.h
+++ b/common/stack.h
@@ -30,48 +30,59 @@ namespace Common {
/**
* Extremly simple fixed size stack class.
*/
-template<class T, int MAX_SIZE = 10>
+template<class T, uint MAX_SIZE = 10>
class FixedStack {
-protected:
- T _stack[MAX_SIZE];
- int _size;
public:
+ typedef uint size_type;
+
FixedStack<T, MAX_SIZE>() : _size(0) {}
bool empty() const {
return _size <= 0;
}
+
void clear() {
_size = 0;
}
+
void push(const T &x) {
assert(_size < MAX_SIZE);
_stack[_size++] = x;
}
+
const T &top() const {
assert(_size > 0);
return _stack[_size - 1];
}
+
T &top() {
assert(_size > 0);
return _stack[_size - 1];
}
+
T pop() {
T tmp = top();
--_size;
return tmp;
}
- int size() const {
+
+ size_type size() const {
return _size;
}
- T &operator[](int i) {
- assert(0 <= i && i < MAX_SIZE);
+
+ T &operator[](size_type i) {
+ assert(i < MAX_SIZE);
return _stack[i];
}
- const T &operator[](int i) const {
- assert(0 <= i && i < MAX_SIZE);
+
+ const T &operator[](size_type i) const {
+ assert(i < MAX_SIZE);
return _stack[i];
}
+
+protected:
+ T _stack[MAX_SIZE];
+ size_type _size;
};
@@ -81,39 +92,49 @@ public:
template<class T>
class Stack {
private:
- Array<T> _stack;
+ Array<T> _stack;
public:
+ typedef typename Array<T>::size_type size_type;
+
Stack<T>() {}
Stack<T>(const Array<T> &stackContent) : _stack(stackContent) {}
bool empty() const {
return _stack.empty();
}
+
void clear() {
_stack.clear();
}
+
void push(const T &x) {
_stack.push_back(x);
}
+
T &top() {
return _stack.back();
}
+
const T &top() const {
return _stack.back();
}
+
T pop() {
T tmp = _stack.back();
_stack.pop_back();
return tmp;
}
- int size() const {
+
+ size_type size() const {
return _stack.size();
}
- T &operator[](int i) {
+
+ T &operator[](size_type i) {
return _stack[i];
}
- const T &operator[](int i) const {
+
+ const T &operator[](size_type i) const {
return _stack[i];
}
};
diff --git a/common/str.cpp b/common/str.cpp
index 32f4b44e79..84805082ac 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -405,13 +405,13 @@ void String::trim() {
makeUnique();
// Trim trailing whitespace
- while (_size >= 1 && isspace(static_cast<unsigned char>(_str[_size - 1])))
+ while (_size >= 1 && isSpace(_str[_size - 1]))
--_size;
_str[_size] = 0;
// Trim leading whitespace
char *t = _str;
- while (isspace((unsigned char)*t))
+ while (isSpace(*t))
t++;
if (t != _str) {
@@ -606,14 +606,14 @@ String operator+(const String &x, char y) {
}
char *ltrim(char *t) {
- while (isspace(static_cast<unsigned char>(*t)))
+ while (isSpace(*t))
t++;
return t;
}
char *rtrim(char *t) {
int l = strlen(t) - 1;
- while (l >= 0 && isspace(static_cast<unsigned char>(t[l])))
+ while (l >= 0 && isSpace(t[l]))
t[l--] = 0;
return t;
}
@@ -793,7 +793,7 @@ size_t strlcpy(char *dst, const char *src, size_t size) {
}
// Move to the terminating zero of the source
- // string, we need this to determin the length
+ // string, we need this to determine the length
// of the source string.
while (*src)
++src;
@@ -841,7 +841,7 @@ size_t strlcat(char *dst, const char *src, size_t size) {
*dst = 0;
// Move to the terminating zero of the source
- // string, we need this to determin the length
+ // string, we need this to determine the length
// of the source string.
while (*src)
++src;
diff --git a/common/stream.cpp b/common/stream.cpp
index 30b3bca497..85647bfe3a 100644
--- a/common/stream.cpp
+++ b/common/stream.cpp
@@ -240,7 +240,7 @@ bool SeekableSubReadStream::seek(int32 offset, int whence) {
return ret;
}
-uint32 SafeSubReadStream::read(void *dataPtr, uint32 dataSize) {
+uint32 SafeSeekableSubReadStream::read(void *dataPtr, uint32 dataSize) {
// Make sure the parent stream is at the right position
seek(0, SEEK_CUR);
diff --git a/common/substream.h b/common/substream.h
index 7e67389da1..01686529aa 100644
--- a/common/substream.h
+++ b/common/substream.h
@@ -99,21 +99,24 @@ public:
* normal SeekableSubReadStream, at the cost of seek()ing the parent stream
* before each read().
*
- * More than one SafeSubReadStream to the same parent stream can be used
+ * More than one SafeSeekableSubReadStream to the same parent stream can be used
* at the same time; they won't mess up each other. They will, however,
* reposition the parent stream, so don't depend on its position to be
- * the same after a read() or seek() on one of its SafeSubReadStream.
+ * the same after a read() or seek() on one of its SafeSeekableSubReadStream.
+ *
+ * Note that this stream is *not* threading safe. Calling read from the audio
+ * thread and from the main thread might mess up the data retrieved.
*/
-class SafeSubReadStream : public SeekableSubReadStream {
+class SafeSeekableSubReadStream : public SeekableSubReadStream {
public:
- SafeSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO) :
- SeekableSubReadStream(parentStream, begin, end, disposeParentStream) {
+ SafeSeekableSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO)
+ : SeekableSubReadStream(parentStream, begin, end, disposeParentStream) {
}
- virtual uint32 read(void *dataPtr, uint32 dataSize);
+ virtual uint32 read(void *dataPtr, uint32 dataSize);
};
-} // End of namespace Common
+} // End of namespace Common
#endif
diff --git a/common/system.h b/common/system.h
index 413fe326a7..dc74533861 100644
--- a/common/system.h
+++ b/common/system.h
@@ -51,7 +51,11 @@ class UpdateManager;
class TimerManager;
class SeekableReadStream;
class WriteStream;
-class HardwareKeySet;
+#ifdef ENABLE_KEYMAPPER
+class HardwareInputSet;
+class Keymap;
+class KeymapperDefaultBindings;
+#endif
}
class AudioCDManager;
@@ -932,15 +936,42 @@ public:
return _eventManager;
}
+#ifdef ENABLE_KEYMAPPER
+ /**
+ * Register hardware inputs with keymapper
+ * IMPORTANT NOTE: This is part of the WIP Keymapper. If you plan to use
+ * this, please talk to tsoliman and/or LordHoto.
+ *
+ * @return HardwareInputSet with all keys and recommended mappings
+ *
+ * See keymapper documentation for further reference.
+ */
+ virtual Common::HardwareInputSet *getHardwareInputSet() { return 0; }
+
/**
- * Register hardware keys with keymapper
+ * Return a platform-specific global keymap
+ * IMPORTANT NOTE: This is part of the WIP Keymapper. If you plan to use
+ * this, please talk to tsoliman and/or LordHoto.
*
- * @return HardwareKeySet with all keys and recommended mappings
+ * @return Keymap with actions appropriate for the platform
+ *
+ * The caller will use and delete the return object.
*
* See keymapper documentation for further reference.
*/
- virtual Common::HardwareKeySet *getHardwareKeySet() { return 0; }
+ virtual Common::Keymap *getGlobalKeymap() { return 0; }
+ /**
+ * Return platform-specific default keybindings
+ * IMPORTANT NOTE: This is part of the WIP Keymapper. If you plan to use
+ * this, please talk to tsoliman and/or LordHoto.
+ *
+ * @return KeymapperDefaultBindings populated with keybindings
+ *
+ * See keymapper documentation for further reference.
+ */
+ virtual Common::KeymapperDefaultBindings *getKeymapperDefaultBindings() { return 0; }
+#endif
//@}
diff --git a/common/translation.cpp b/common/translation.cpp
index 081bde987d..2bc31c617b 100644
--- a/common/translation.cpp
+++ b/common/translation.cpp
@@ -26,7 +26,7 @@
#undef ARRAYSIZE
#endif
-#define TRANSLATIONS_DAT_VER 2
+#define TRANSLATIONS_DAT_VER 3
#include "common/translation.h"
#include "common/config-manager.h"
@@ -45,7 +45,7 @@ bool operator<(const TLanguage &l, const TLanguage &r) {
return strcmp(l.name, r.name) < 0;
}
-TranslationManager::TranslationManager() : _currentLang(-1) {
+TranslationManager::TranslationManager() : _currentLang(-1), _charmap(0) {
loadTranslationsInfoDat();
// Set the default language
@@ -53,6 +53,7 @@ TranslationManager::TranslationManager() : _currentLang(-1) {
}
TranslationManager::~TranslationManager() {
+ delete[] _charmap;
}
int32 TranslationManager::findMatchingLanguage(const String &lang) {
@@ -231,8 +232,9 @@ bool TranslationManager::openTranslationsFile(File &inFile) {
ArchiveMemberList fileList;
SearchMan.listMatchingMembers(fileList, "translations.dat");
for (ArchiveMemberList::iterator it = fileList.begin(); it != fileList.end(); ++it) {
- SeekableReadStream *stream = it->get()->createReadStream();
- if (stream && inFile.open(stream, it->get()->getName())) {
+ ArchiveMember const &m = **it;
+ SeekableReadStream *const stream = m.createReadStream();
+ if (stream && inFile.open(stream, m.getName())) {
if (checkHeader(inFile))
return true;
inFile.close();
@@ -289,9 +291,14 @@ void TranslationManager::loadTranslationsInfoDat() {
// Get number of translations
int nbTranslations = in.readUint16BE();
- // Skip all the block sizes
- for (int i = 0; i < nbTranslations + 2; ++i)
- in.readUint16BE();
+ // Get number of codepages
+ int nbCodepages = in.readUint16BE();
+
+ // Determine where the codepages start
+ _charmapStart = 0;
+ for (int i = 0; i < nbTranslations + 3; ++i)
+ _charmapStart += in.readUint16BE();
+ _charmapStart += in.pos();
// Read list of languages
_langs.resize(nbTranslations);
@@ -305,6 +312,14 @@ void TranslationManager::loadTranslationsInfoDat() {
_langNames[i] = String(buf, len - 1);
}
+ // Read list of codepages
+ _charmaps.resize(nbCodepages);
+ for (int i = 0; i < nbCodepages; ++i) {
+ len = in.readUint16BE();
+ in.read(buf, len);
+ _charmaps[i] = String(buf, len - 1);
+ }
+
// Read messages
int numMessages = in.readUint16BE();
_messageIds.resize(numMessages);
@@ -344,9 +359,16 @@ void TranslationManager::loadLanguageDat(int index) {
return;
}
+ // Get the number of codepages
+ int nbCodepages = in.readUint16BE();
+ if (nbCodepages != (int)_charmaps.size()) {
+ warning("The 'translations.dat' file has changed since starting ScummVM. GUI translation will not be available");
+ return;
+ }
+
// Get size of blocks to skip.
int skipSize = 0;
- for (int i = 0; i < index + 2; ++i)
+ for (int i = 0; i < index + 3; ++i)
skipSize += in.readUint16BE();
// We also need to skip the remaining block sizes
skipSize += 2 * (nbTranslations - index);
@@ -380,6 +402,29 @@ void TranslationManager::loadLanguageDat(int index) {
_currentTranslationMessages[i].msgctxt = String(buf, len - 1);
}
}
+
+ // Find the charset
+ int charmapNum = -1;
+ for (uint i = 0; i < _charmaps.size(); ++i) {
+ if (_charmaps[i].equalsIgnoreCase(_currentCharset)) {
+ charmapNum = i;
+ break;
+ }
+ }
+
+ // Setup the new charset mapping
+ if (charmapNum == -1) {
+ delete[] _charmap;
+ _charmap = 0;
+ } else {
+ if (!_charmap)
+ _charmap = new uint32[256];
+
+ in.seek(_charmapStart + charmapNum * 256 * 4, SEEK_SET);
+ for (int i = 0; i < 256; ++i)
+ _charmap[i] = in.readUint32BE();
+ }
+
}
bool TranslationManager::checkHeader(File &in) {
diff --git a/common/translation.h b/common/translation.h
index 71cf2b0981..77e2fdfc07 100644
--- a/common/translation.h
+++ b/common/translation.h
@@ -154,6 +154,21 @@ public:
String getCurrentCharset() const;
/**
+ * Returns a pointer to the current charset mapping. This mapping is a
+ * codepage encoding -> unicode mapping and always 256 entries long.
+ *
+ * The MSB of the individual mapped (i.e. unicode) character states
+ * whether the character is required for this charset. If it is set, the
+ * character needs to be present in order to have the text displayed.
+ * This is used in the font loading code to detect whether the font is
+ * able of supporting this language.
+ *
+ * The return value might be 0 in case it's a default ASCII/ISO-8859-1
+ * map.
+ */
+ const uint32 *getCharsetMapping() const { return _charmap; }
+
+ /**
* Returns currently selected translation language
*/
String getCurrentLanguage() const;
@@ -200,11 +215,15 @@ private:
StringArray _langs;
StringArray _langNames;
+ StringArray _charmaps;
StringArray _messageIds;
Array<PoMessageEntry> _currentTranslationMessages;
String _currentCharset;
int _currentLang;
+
+ uint32 _charmapStart;
+ uint32 *_charmap;
};
} // End of namespace Common
diff --git a/common/unarj.cpp b/common/unarj.cpp
index cccc330bb5..fe3c17a2ac 100644
--- a/common/unarj.cpp
+++ b/common/unarj.cpp
@@ -701,9 +701,9 @@ public:
virtual ~ArjArchive();
// Archive implementation
- virtual bool hasFile(const String &name);
- virtual int listMembers(ArchiveMemberList &list);
- virtual ArchiveMemberPtr getMember(const String &name);
+ virtual bool hasFile(const String &name) const;
+ virtual int listMembers(ArchiveMemberList &list) const;
+ virtual const ArchiveMemberPtr getMember(const String &name) const;
virtual SeekableReadStream *createReadStreamForMember(const String &name) const;
};
@@ -745,14 +745,14 @@ ArjArchive::~ArjArchive() {
}
}
-bool ArjArchive::hasFile(const String &name) {
+bool ArjArchive::hasFile(const String &name) const {
return _headers.contains(name);
}
-int ArjArchive::listMembers(ArchiveMemberList &list) {
+int ArjArchive::listMembers(ArchiveMemberList &list) const {
int matches = 0;
- ArjHeadersMap::iterator it = _headers.begin();
+ ArjHeadersMap::const_iterator it = _headers.begin();
for ( ; it != _headers.end(); ++it) {
list.push_back(ArchiveMemberList::value_type(new GenericArchiveMember(it->_value->filename, this)));
matches++;
@@ -761,7 +761,7 @@ int ArjArchive::listMembers(ArchiveMemberList &list) {
return matches;
}
-ArchiveMemberPtr ArjArchive::getMember(const String &name) {
+const ArchiveMemberPtr ArjArchive::getMember(const String &name) const {
if (!hasFile(name))
return ArchiveMemberPtr();
diff --git a/common/unzip.cpp b/common/unzip.cpp
index 8650c91866..8cfcd605fa 100644
--- a/common/unzip.cpp
+++ b/common/unzip.cpp
@@ -111,7 +111,7 @@ typedef struct {
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
/* like the STRICT of WIN32, we define a pointer that cannot be converted
- from (void*) without cast */
+ from (void *) without cast */
typedef struct TagunzFile__ { int unused; } unzFile__;
typedef unzFile__ *unzFile;
#else
@@ -1062,7 +1062,7 @@ int unzOpenCurrentFile (unzFile file) {
if (pfile_in_zip_read_info==NULL)
return UNZ_INTERNALERROR;
- pfile_in_zip_read_info->read_buffer=(char*)malloc(UNZ_BUFSIZE);
+ pfile_in_zip_read_info->read_buffer=(char *)malloc(UNZ_BUFSIZE);
pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
pfile_in_zip_read_info->pos_local_extrafield=0;
@@ -1151,7 +1151,7 @@ int unzReadCurrentFile(unzFile file, voidp buf, unsigned len) {
if (len==0)
return 0;
- pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
+ pfile_in_zip_read_info->stream.next_out = (Bytef *)buf;
pfile_in_zip_read_info->stream.avail_out = (uInt)len;
@@ -1177,7 +1177,7 @@ int unzReadCurrentFile(unzFile file, voidp buf, unsigned len) {
pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
- pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->read_buffer;
+ pfile_in_zip_read_info->stream.next_in = (Bytef *)pfile_in_zip_read_info->read_buffer;
pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
}
@@ -1426,9 +1426,9 @@ public:
~ZipArchive();
- virtual bool hasFile(const String &name);
- virtual int listMembers(ArchiveMemberList &list);
- virtual ArchiveMemberPtr getMember(const String &name);
+ virtual bool hasFile(const String &name) const;
+ virtual int listMembers(ArchiveMemberList &list) const;
+ virtual const ArchiveMemberPtr getMember(const String &name) const;
virtual SeekableReadStream *createReadStreamForMember(const String &name) const;
};
@@ -1458,11 +1458,11 @@ ZipArchive::~ZipArchive() {
unzClose(_zipFile);
}
-bool ZipArchive::hasFile(const String &name) {
+bool ZipArchive::hasFile(const String &name) const {
return (unzLocateFile(_zipFile, name.c_str(), 2) == UNZ_OK);
}
-int ZipArchive::listMembers(ArchiveMemberList &list) {
+int ZipArchive::listMembers(ArchiveMemberList &list) const {
int matches = 0;
int err = unzGoToFirstFile(_zipFile);
@@ -1481,7 +1481,7 @@ int ZipArchive::listMembers(ArchiveMemberList &list) {
return matches;
}
-ArchiveMemberPtr ZipArchive::getMember(const String &name) {
+const ArchiveMemberPtr ZipArchive::getMember(const String &name) const {
if (!hasFile(name))
return ArchiveMemberPtr();
diff --git a/common/util.cpp b/common/util.cpp
index 1c4df8b6cd..4d9ff11c5c 100644
--- a/common/util.cpp
+++ b/common/util.cpp
@@ -19,9 +19,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#define FORBIDDEN_SYMBOL_EXCEPTION_isalnum
+#define FORBIDDEN_SYMBOL_EXCEPTION_isalpha
+#define FORBIDDEN_SYMBOL_EXCEPTION_isdigit
+#define FORBIDDEN_SYMBOL_EXCEPTION_isnumber
+#define FORBIDDEN_SYMBOL_EXCEPTION_islower
+#define FORBIDDEN_SYMBOL_EXCEPTION_isspace
+#define FORBIDDEN_SYMBOL_EXCEPTION_isupper
+
+
#include "common/util.h"
-#include "common/translation.h"
-#include "common/config-manager.h"
#include "common/debug.h"
namespace Common {
@@ -103,307 +110,38 @@ bool parseBool(const String &val, bool &valAsBool) {
#pragma mark -
-const LanguageDescription g_languages[] = {
- { "zh-cn", "zh_CN", "Chinese (China)", ZH_CNA },
- { "zh", "zh_TW", "Chinese (Taiwan)", ZH_TWN },
- { "cz", "cs_CZ", "Czech", CZ_CZE },
- { "nl", "nl_NL", "Dutch", NL_NLD },
- { "en", "en", "English", EN_ANY }, // Generic English (when only one game version exist)
- { "gb", "en_GB", "English (GB)", EN_GRB },
- { "us", "en_US", "English (US)", EN_USA },
- { "fr", "fr_FR", "French", FR_FRA },
- { "de", "de_DE", "German", DE_DEU },
- { "gr", "el_GR", "Greek", GR_GRE },
- { "he", "he_IL", "Hebrew", HE_ISR },
- { "hb", "he_IL", "Hebrew", HE_ISR }, // Deprecated
- { "hr", "hr_HR", "Croatian", HR_HRV },
- { "hu", "hu_HU", "Hungarian", HU_HUN },
- { "it", "it_IT", "Italian", IT_ITA },
- { "jp", "ja_JP", "Japanese", JA_JPN },
- { "kr", "ko_KR", "Korean", KO_KOR },
- { "nb", "nb_NO", "Norwegian Bokm\xE5l", NB_NOR }, // TODO Someone should verify the unix locale
- { "pl", "pl_PL", "Polish", PL_POL },
- { "br", "pt_BR", "Portuguese", PT_BRA },
- { "ru", "ru_RU", "Russian", RU_RUS },
- { "es", "es_ES", "Spanish", ES_ESP },
- { "se", "sv_SE", "Swedish", SE_SWE },
- { 0, 0, 0, UNK_LANG }
-};
-
-Language parseLanguage(const String &str) {
- if (str.empty())
- return UNK_LANG;
+#define ENSURE_ASCII_CHAR(c) \
+ if (c < 0 || c > 127) \
+ return false
- const LanguageDescription *l = g_languages;
- for (; l->code; ++l) {
- if (str.equalsIgnoreCase(l->code))
- return l->id;
- }
-
- return UNK_LANG;
+bool isAlnum(int c) {
+ ENSURE_ASCII_CHAR(c);
+ return isalnum((byte)c);
}
-Language parseLanguageFromLocale(const char *locale) {
- if (!locale || !*locale)
- return UNK_LANG;
-
- const LanguageDescription *l = g_languages;
- for (; l->code; ++l) {
- if (!strcmp(l->unixLocale, locale))
- return l->id;
- }
-
- return UNK_LANG;
-}
-
-const char *getLanguageCode(Language id) {
- const LanguageDescription *l = g_languages;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->code;
- }
- return 0;
-}
-
-const char *getLanguageLocale(Language id) {
- const LanguageDescription *l = g_languages;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->unixLocale;
- }
- return 0;
-}
-
-const char *getLanguageDescription(Language id) {
- const LanguageDescription *l = g_languages;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->description;
- }
- return 0;
-}
-
-
-#pragma mark -
-
-
-const PlatformDescription g_platforms[] = {
- { "2gs", "2gs", "2gs", "Apple IIgs", kPlatformApple2GS },
- { "3do", "3do", "3do", "3DO", kPlatform3DO },
- { "acorn", "acorn", "acorn", "Acorn", kPlatformAcorn },
- { "amiga", "ami", "amiga", "Amiga", kPlatformAmiga },
- { "atari", "atari-st", "st", "Atari ST", kPlatformAtariST },
- { "c64", "c64", "c64", "Commodore 64", kPlatformC64 },
- { "pc", "dos", "ibm", "DOS", kPlatformPC },
- { "pc98", "pc98", "pc98", "PC-98", kPlatformPC98 },
- { "wii", "wii", "wii", "Nintendo Wii", kPlatformWii },
- { "coco3", "coco3", "coco3", "CoCo3", kPlatformCoCo3 },
-
- // The 'official' spelling seems to be "FM-TOWNS" (e.g. in the Indy4 demo).
- // However, on the net many variations can be seen, like "FMTOWNS",
- // "FM TOWNS", "FmTowns", etc.
- { "fmtowns", "towns", "fm", "FM-TOWNS", kPlatformFMTowns },
-
- { "linux", "linux", "linux", "Linux", kPlatformLinux },
- { "macintosh", "mac", "mac", "Macintosh", kPlatformMacintosh },
- { "pce", "pce", "pce", "PC-Engine", kPlatformPCEngine },
- { "nes", "nes", "nes", "NES", kPlatformNES },
- { "segacd", "segacd", "sega", "SegaCD", kPlatformSegaCD },
- { "windows", "win", "win", "Windows", kPlatformWindows },
- { "playstation", "psx", "psx", "Sony PlayStation", kPlatformPSX },
- { "cdi", "cdi", "cdi", "Philips CD-i", kPlatformCDi },
- { "ios", "ios", "ios", "Apple iOS", kPlatformIOS },
-
- { 0, 0, 0, "Default", kPlatformUnknown }
-};
-
-Platform parsePlatform(const String &str) {
- if (str.empty())
- return kPlatformUnknown;
-
- // Handle some special case separately, for compatibility with old config
- // files.
- if (str == "1")
- return kPlatformAmiga;
- else if (str == "2")
- return kPlatformAtariST;
- else if (str == "3")
- return kPlatformMacintosh;
-
- const PlatformDescription *l = g_platforms;
- for (; l->code; ++l) {
- if (str.equalsIgnoreCase(l->code) || str.equalsIgnoreCase(l->code2) || str.equalsIgnoreCase(l->abbrev))
- return l->id;
- }
-
- return kPlatformUnknown;
+bool isAlpha(int c) {
+ ENSURE_ASCII_CHAR(c);
+ return isalpha((byte)c);
}
-
-const char *getPlatformCode(Platform id) {
- const PlatformDescription *l = g_platforms;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->code;
- }
- return 0;
+bool isDigit(int c) {
+ ENSURE_ASCII_CHAR(c);
+ return isdigit((byte)c);
}
-const char *getPlatformAbbrev(Platform id) {
- const PlatformDescription *l = g_platforms;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->abbrev;
- }
- return 0;
+bool isLower(int c) {
+ ENSURE_ASCII_CHAR(c);
+ return islower((byte)c);
}
-const char *getPlatformDescription(Platform id) {
- const PlatformDescription *l = g_platforms;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->description;
- }
- return l->description;
+bool isSpace(int c) {
+ ENSURE_ASCII_CHAR(c);
+ return isspace((byte)c);
}
-
-#pragma mark -
-
-
-const RenderModeDescription g_renderModes[] = {
- // I18N: Hercules is graphics card name
- { "hercGreen", _s("Hercules Green"), kRenderHercG },
- { "hercAmber", _s("Hercules Amber"), kRenderHercA },
- { "cga", "CGA", kRenderCGA },
- { "ega", "EGA", kRenderEGA },
- { "amiga", "Amiga", kRenderAmiga },
- {0, 0, kRenderDefault}
-};
-
-DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Hercules Green", "lowres")
-DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Hercules Amber", "lowres")
-
-RenderMode parseRenderMode(const String &str) {
- if (str.empty())
- return kRenderDefault;
-
- const RenderModeDescription *l = g_renderModes;
- for (; l->code; ++l) {
- if (str.equalsIgnoreCase(l->code))
- return l->id;
- }
-
- return kRenderDefault;
-}
-
-const char *getRenderModeCode(RenderMode id) {
- const RenderModeDescription *l = g_renderModes;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->code;
- }
- return 0;
-}
-
-const char *getRenderModeDescription(RenderMode id) {
- const RenderModeDescription *l = g_renderModes;
- for (; l->code; ++l) {
- if (l->id == id)
- return l->description;
- }
- return 0;
-}
-
-const struct GameOpt {
- const char *option;
- const char *desc;
-} g_gameOptions[] = {
- { GUIO_NOSUBTITLES, "sndNoSubs" },
- { GUIO_NOMUSIC, "sndNoMusic" },
- { GUIO_NOSPEECH, "sndNoSpeech" },
- { GUIO_NOSFX, "sndNoSFX" },
- { GUIO_NOMIDI, "sndNoMIDI" },
-
- { GUIO_NOLAUNCHLOAD, "launchNoLoad" },
-
- { GUIO_MIDIPCSPK, "midiPCSpk" },
- { GUIO_MIDICMS, "midiCMS" },
- { GUIO_MIDIPCJR, "midiPCJr" },
- { GUIO_MIDIADLIB, "midiAdLib" },
- { GUIO_MIDIC64, "midiC64" },
- { GUIO_MIDIAMIGA, "midiAmiga" },
- { GUIO_MIDIAPPLEIIGS,"midiAppleIIgs" },
- { GUIO_MIDITOWNS, "midiTowns" },
- { GUIO_MIDIPC98, "midiPC98" },
- { GUIO_MIDIMT32, "midiMt32" },
- { GUIO_MIDIGM, "midiGM" },
-
- { GUIO_NOASPECT, "noAspect" },
- { GUIO_EGAUNDITHER, "egaUndither" },
-
- { GUIO_NONE, 0 }
-};
-
-bool checkGameGUIOption(const String &option, const String &str) {
- for (int i = 0; g_gameOptions[i].desc; i++) {
- if (option.contains(g_gameOptions[i].option)) {
- if (str.contains(g_gameOptions[i].desc))
- return true;
- else
- return false;
- }
- }
- return false;
-}
-
-bool checkGameGUIOptionLanguage(Language lang, const String &str) {
- if (!str.contains("lang_")) // If no languages are specified
- return true;
-
- if (str.contains(getGameGUIOptionsDescriptionLanguage(lang)))
- return true;
-
- return false;
-}
-
-const String getGameGUIOptionsDescriptionLanguage(Language lang) {
- if (lang == UNK_LANG)
- return "";
-
- return String(String("lang_") + getLanguageDescription(lang));
-}
-
-String parseGameGUIOptions(const String &str) {
- Common::String res;
-
- for (int i = 0; g_gameOptions[i].desc; i++)
- if (str.contains(g_gameOptions[i].desc))
- res += g_gameOptions[i].option;
-
- return res;
-}
-
-const String getGameGUIOptionsDescription(const String &options) {
- String res;
-
- for (int i = 0; g_gameOptions[i].desc; i++)
- if (options.contains(g_gameOptions[i].option[0]))
- res += String(g_gameOptions[i].desc) + " ";
-
- res.trim();
-
- return res;
-}
-
-void updateGameGUIOptions(const String &options, const String &langOption) {
- const String newOptionString = getGameGUIOptionsDescription(options) + " " + langOption;
-
- if ((!options.empty() && !ConfMan.hasKey("guioptions")) ||
- (ConfMan.hasKey("guioptions") && ConfMan.get("guioptions") != newOptionString)) {
- ConfMan.set("guioptions", newOptionString);
- ConfMan.flushToDisk();
- }
+bool isUpper(int c) {
+ ENSURE_ASCII_CHAR(c);
+ return isupper((byte)c);
}
} // End of namespace Common
diff --git a/common/util.h b/common/util.h
index dfa57d7259..b90be0675b 100644
--- a/common/util.h
+++ b/common/util.h
@@ -25,7 +25,6 @@
#include "common/scummsys.h"
#include "common/str.h"
-
/**
* Check whether a given pointer is aligned correctly.
* Note that 'alignment' must be a power of two!
@@ -78,36 +77,6 @@ template<typename T> inline void SWAP(T &a, T &b) { T tmp = a; a = b; b = tmp; }
# define SCUMMVM_CURRENT_FUNCTION "<unknown>"
#endif
-#define GUIO_NONE "\000"
-#define GUIO_NOSUBTITLES "\001"
-#define GUIO_NOMUSIC "\002"
-#define GUIO_NOSPEECH "\003"
-#define GUIO_NOSFX "\004"
-#define GUIO_NOMIDI "\005"
-#define GUIO_NOLAUNCHLOAD "\006"
-
-#define GUIO_MIDIPCSPK "\007"
-#define GUIO_MIDICMS "\010"
-#define GUIO_MIDIPCJR "\011"
-#define GUIO_MIDIADLIB "\012"
-#define GUIO_MIDIC64 "\013"
-#define GUIO_MIDIAMIGA "\014"
-#define GUIO_MIDIAPPLEIIGS "\015"
-#define GUIO_MIDITOWNS "\016"
-#define GUIO_MIDIPC98 "\017"
-#define GUIO_MIDIMT32 "\020"
-#define GUIO_MIDIGM "\021"
-
-#define GUIO_NOASPECT "\022"
-#define GUIO_EGAUNDITHER "\023"
-
-#define GUIO0() (GUIO_NONE)
-#define GUIO1(a) (a)
-#define GUIO2(a,b) (a b)
-#define GUIO3(a,b,c) (a b c)
-#define GUIO4(a,b,c,d) (a b c d)
-#define GUIO5(a,b,c,d,e) (a b c d e)
-
namespace Common {
/**
@@ -133,140 +102,68 @@ extern void hexdump(const byte * data, int len, int bytesPerLine = 16, int start
*/
bool parseBool(const String &val, bool &valAsBool);
+
/**
- * List of game language.
+ * Test whether the given character is alphanumeric (a-z, A-Z, 0-9).
+ * If the parameter is outside the range of a signed or unsigned char, then
+ * false is returned.
+ *
+ * @param c the character to test
+ * @return true if the character is alphanumeric, false otherwise.
*/
-enum Language {
- ZH_CNA,
- ZH_TWN,
- CZ_CZE,
- NL_NLD,
- EN_ANY, // Generic English (when only one game version exist)
- EN_GRB,
- EN_USA,
- FR_FRA,
- DE_DEU,
- GR_GRE,
- HE_ISR,
- HR_HRV,
- HU_HUN,
- IT_ITA,
- JA_JPN,
- KO_KOR,
- NB_NOR,
- PL_POL,
- PT_BRA,
- RU_RUS,
- ES_ESP,
- SE_SWE,
-
- UNK_LANG = -1 // Use default language (i.e. none specified)
-};
-
-struct LanguageDescription {
- const char *code;
- const char *unixLocale;
- const char *description;
- Language id;
-};
-
-extern const LanguageDescription g_languages[];
-
-
-/** Convert a string containing a language name into a Language enum value. */
-extern Language parseLanguage(const String &str);
-extern Language parseLanguageFromLocale(const char *locale);
-extern const char *getLanguageCode(Language id);
-extern const char *getLanguageLocale(Language id);
-extern const char *getLanguageDescription(Language id);
+bool isAlnum(int c);
/**
- * List of game platforms. Specifying a platform for a target can be used to
- * give the game engines a hint for which platform the game data file are.
- * This may be optional or required, depending on the game engine and the
- * game in question.
+ * Test whether the given character is an alphabetic letter (a-z, A-Z).
+ * If the parameter is outside the range of a signed or unsigned char, then
+ * false is returned.
+ *
+ * @param c the character to test
+ * @return true if the character is TODO, false otherwise.
*/
-enum Platform {
- kPlatformPC,
- kPlatformAmiga,
- kPlatformAtariST,
- kPlatformMacintosh,
- kPlatformFMTowns,
- kPlatformWindows,
- kPlatformNES,
- kPlatformC64,
- kPlatformCoCo3,
- kPlatformLinux,
- kPlatformAcorn,
- kPlatformSegaCD,
- kPlatform3DO,
- kPlatformPCEngine,
- kPlatformApple2GS,
- kPlatformPC98,
- kPlatformWii,
- kPlatformPSX,
- kPlatformCDi,
- kPlatformIOS,
-
- kPlatformUnknown = -1
-};
-
-struct PlatformDescription {
- const char *code;
- const char *code2;
- const char *abbrev;
- const char *description;
- Platform id;
-};
-
-extern const PlatformDescription g_platforms[];
-
-/** Convert a string containing a platform name into a Platform enum value. */
-extern Platform parsePlatform(const String &str);
-extern const char *getPlatformCode(Platform id);
-extern const char *getPlatformAbbrev(Platform id);
-extern const char *getPlatformDescription(Platform id);
+bool isAlpha(int c);
/**
- * List of render modes. It specifies which original graphics mode
- * to use. Some targets used postprocessing dithering routines for
- * reducing color depth of final image which let it to be rendered on
- * such low-level adapters as CGA or Hercules.
+ * Test whether the given character is a decimal-digit (0-9).
+ * If the parameter is outside the range of a signed or unsigned char, then
+ * false is returned.
+ *
+ * @param c the character to test
+ * @return true if the character is a decimal-digit, false otherwise.
*/
-enum RenderMode {
- kRenderDefault = 0,
- kRenderEGA = 1,
- kRenderCGA = 2,
- kRenderHercG = 3,
- kRenderHercA = 4,
- kRenderAmiga = 5
-};
+bool isDigit(int c);
-struct RenderModeDescription {
- const char *code;
- const char *description;
- RenderMode id;
-};
-
-extern const RenderModeDescription g_renderModes[];
-
-/** Convert a string containing a render mode name into a RenderingMode enum value. */
-extern RenderMode parseRenderMode(const String &str);
-extern const char *getRenderModeCode(RenderMode id);
-extern const char *getRenderModeDescription(RenderMode id);
+/**
+ * Test whether the given character is a lower-case letter (a-z).
+ * If the parameter is outside the range of a signed or unsigned char, then
+ * false is returned.
+ *
+ * @param c the character to test
+ * @return true if the character is a lower-case letter, false otherwise.
+ */
+bool isLower(int c);
-bool checkGameGUIOption(const String &option, const String &str);
-bool checkGameGUIOptionLanguage(Language lang, const String &str);
-String parseGameGUIOptions(const String &str);
-const String getGameGUIOptionsDescription(const String &options);
-const String getGameGUIOptionsDescriptionLanguage(Language lang);
+/**
+ * Test whether the given character is a white-space.
+ * White-space characters are ' ', '\t', '\r', '\n', '\v', '\f'.
+ *
+ * If the parameter is outside the range of a signed or unsigned char, then
+ * false is returned.
+ *
+ * @param c the character to test
+ * @return true if the character is a white-space, false otherwise.
+ */
+bool isSpace(int c);
/**
- * Updates the GUI options of the current config manager
- * domain, when they differ to the ones passed as
- * parameter.
+ * Test whether the given character is an upper-case letter (A-Z).
+ * If the parameter is outside the range of a signed or unsigned char, then
+ * false is returned.
+ *
+ * @param c the character to test
+ * @return true if the character is an upper-case letter, false otherwise.
*/
-void updateGameGUIOptions(const String &options, const String &langOption);
+bool isUpper(int c);
} // End of namespace Common
diff --git a/common/xmlparser.cpp b/common/xmlparser.cpp
index f768e44382..ea3d44cf87 100644
--- a/common/xmlparser.cpp
+++ b/common/xmlparser.cpp
@@ -39,7 +39,7 @@ XMLParser::~XMLParser() {
delete _XMLkeys;
delete _stream;
- for (List<XMLKeyLayout*>::iterator i = _layoutList.begin();
+ for (List<XMLKeyLayout *>::iterator i = _layoutList.begin();
i != _layoutList.end(); ++i)
delete *i;
@@ -263,7 +263,7 @@ bool XMLParser::vparseIntegerKey(const char *key, int count, va_list args) {
int *num_ptr;
while (count--) {
- while (isspace(static_cast<unsigned char>(*key)))
+ while (isSpace(*key))
key++;
num_ptr = va_arg(args, int*);
@@ -271,7 +271,7 @@ bool XMLParser::vparseIntegerKey(const char *key, int count, va_list args) {
key = parseEnd;
- while (isspace(static_cast<unsigned char>(*key)))
+ while (isSpace(*key))
key++;
if (count && *key++ != ',')
@@ -463,10 +463,10 @@ bool XMLParser::parse() {
}
bool XMLParser::skipSpaces() {
- if (!isspace(static_cast<unsigned char>(_char)))
+ if (!isSpace(_char))
return false;
- while (_char && isspace(static_cast<unsigned char>(_char)))
+ while (_char && isSpace(_char))
_char = _stream->readByte();
return true;
@@ -516,7 +516,7 @@ bool XMLParser::parseToken() {
_char = _stream->readByte();
}
- return isspace(static_cast<unsigned char>(_char)) != 0 || _char == '>' || _char == '=' || _char == '/';
+ return isSpace(_char) != 0 || _char == '>' || _char == '=' || _char == '/';
}
} // End of namespace Common
diff --git a/common/xmlparser.h b/common/xmlparser.h
index 93433b7132..1e474b596c 100644
--- a/common/xmlparser.h
+++ b/common/xmlparser.h
@@ -68,9 +68,9 @@ class SeekableReadStream;
struct CustomXMLKeyLayout : public XMLKeyLayout {\
typedef bool (parserName::*ParserCallback)(ParserNode *node);\
ParserCallback callback;\
- bool doCallback(XMLParser *parent, ParserNode *node) {return ((kLocalParserName*)parent->*callback)(node);} };\
+ bool doCallback(XMLParser *parent, ParserNode *node) {return ((kLocalParserName *)parent->*callback)(node);} };\
virtual void buildLayout() { \
- Common::Stack<XMLKeyLayout*> layout; \
+ Common::Stack<XMLKeyLayout *> layout; \
CustomXMLKeyLayout *lay = 0; \
XMLKeyLayout::XMLKeyProperty prop; \
_XMLkeys = new CustomXMLKeyLayout; \
@@ -295,7 +295,7 @@ protected:
* in their name.
*/
virtual inline bool isValidNameChar(char c) {
- return isalnum(static_cast<unsigned char>(c)) || c == '_';
+ return isAlnum(c) || c == '_';
}
/**
@@ -334,7 +334,7 @@ protected:
*/
virtual void cleanup() {}
- List<XMLKeyLayout*> _layoutList;
+ List<XMLKeyLayout *> _layoutList;
private:
char _char;
@@ -346,7 +346,7 @@ private:
String _error; /** Current error message */
String _token; /** Current text token */
- Stack<ParserNode*> _activeKey; /** Node stack of the parsed keys */
+ Stack<ParserNode *> _activeKey; /** Node stack of the parsed keys */
};
} // End of namespace Common
diff --git a/common/zlib.cpp b/common/zlib.cpp
index 70133fea30..7d765fc539 100644
--- a/common/zlib.cpp
+++ b/common/zlib.cpp
@@ -49,7 +49,7 @@ bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long
return Z_OK == ::uncompress(dst, dstLen, src, srcLen);
}
-bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen) {
+bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen, const byte *dict, uint dictLen) {
if (!dst || !dstLen || !src || !srcLen)
return false;
@@ -68,6 +68,13 @@ bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen)
if (err != Z_OK)
return false;
+ // Set the dictionary, if provided
+ if (dict != 0) {
+ err = inflateSetDictionary(&stream, const_cast<byte *>(dict), dictLen);
+ if (err != Z_OK)
+ return false;
+ }
+
err = inflate(&stream, Z_SYNC_FLUSH);
if (err != Z_OK && err != Z_STREAM_END) {
inflateEnd(&stream);
diff --git a/common/zlib.h b/common/zlib.h
index 7af7df0da8..61322c286a 100644
--- a/common/zlib.h
+++ b/common/zlib.h
@@ -37,7 +37,19 @@ class WriteStream;
* it possible to uncompress data in engines without being forced to link
* them against zlib, thus simplifying the build system.
*
- * @return true on success (i.e. Z_OK), false otherwise
+ * Taken from the zlib manual:
+ * Decompresses the src buffer into the dst buffer.
+ * srcLen is the byte length of the source buffer. Upon entry, dstLen is the
+ * total size of the destination buffer, which must be large enough to hold
+ * the entire uncompressed data. Upon exit, dstLen is the actual size of the
+ * compressed buffer.
+ *
+ * @param dst the buffer to store into.
+ * @param dstLen a pointer to the size of the destination buffer.
+ * @param src the data to be decompressed.
+ * @param srcLen the size of the compressed data.
+ *
+ * @return true on success (i.e. Z_OK), false otherwise.
*/
bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long srcLen);
@@ -46,9 +58,24 @@ bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long
* necessary inflate functions to uncompress data compressed with deflate
* but *not* with the standard zlib header.
*
- * @return true on success (Z_OK or Z_STREAM_END), false otherwise
+ * Decompresses the src buffer into the dst buffer.
+ * srcLen is the byte length of the source buffer, dstLen is the byte
+ * length of the output buffer.
+ * It decompress as much data as possible, up to dstLen bytes.
+ * If a dictionary is provided through the dict buffer, uses it to initializes
+ * the internal decompression dictionary, before the decompression takes place.
+ *
+ * @param dst the buffer to store into.
+ * @param dstLen the size of the destination buffer.
+ * @param src the data to be decompressed.
+ * @param dstLen the size of the compressed data.
+ * @param dict (optional) a decompress dictionary.
+ * @param dictLen (optional) the size of the dictionary.
+ * Mandatory if dict is not 0.
+ *
+ * @return true on success (Z_OK or Z_STREAM_END), false otherwise.
*/
-bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen);
+bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen, const byte *dict = 0, uint dictLen = 0);
#endif