aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoranotherguest2013-11-26 12:14:38 +0100
committeranotherguest2013-11-26 12:14:38 +0100
commit44947f5bdb45095793f1e994385f051d534d53ee (patch)
tree7bfc07044c7a1d585fa5145ef91bfb6f9fb6e242
parented357a6dfacd2fd41366d2baf61bd344fec9a0a0 (diff)
parent0e017f007a8a3db8c8d8320f76cbfd423e662e07 (diff)
downloadscummvm-rg350-44947f5bdb45095793f1e994385f051d534d53ee.tar.gz
scummvm-rg350-44947f5bdb45095793f1e994385f051d534d53ee.tar.bz2
scummvm-rg350-44947f5bdb45095793f1e994385f051d534d53ee.zip
Merge branch 'master' of github.com:scummvm/scummvm
-rw-r--r--.gitignore3
-rw-r--r--Makefile11
-rw-r--r--Makefile.common6
-rw-r--r--common/module.mk1
-rw-r--r--common/str.h7
-rw-r--r--common/ustr.cpp329
-rw-r--r--common/ustr.h194
-rwxr-xr-xconfigure72
-rw-r--r--devtools/create_project/codeblocks.cpp1
-rw-r--r--devtools/create_project/config.h1
-rw-r--r--devtools/create_project/create_project.cpp225
-rw-r--r--devtools/create_project/create_project.h50
-rw-r--r--devtools/create_project/msbuild.cpp2
-rw-r--r--devtools/create_project/visualstudio.cpp2
-rw-r--r--devtools/create_project/xcode.cpp31
-rw-r--r--engines/agi/configure.engine3
-rw-r--r--engines/agos/configure.engine4
-rw-r--r--engines/avalanche/configure.engine3
-rw-r--r--engines/cge/configure.engine3
-rw-r--r--engines/cine/configure.engine3
-rw-r--r--engines/composer/configure.engine3
-rw-r--r--engines/configure.engines57
-rw-r--r--engines/cruise/configure.engine3
-rw-r--r--engines/draci/configure.engine3
-rw-r--r--engines/drascula/configure.engine3
-rw-r--r--engines/dreamweb/configure.engine3
-rw-r--r--engines/engines.mk263
-rw-r--r--engines/fullpipe/configure.engine3
-rw-r--r--engines/gob/configure.engine3
-rw-r--r--engines/groovie/configure.engine4
-rw-r--r--engines/groovie/font.cpp4
-rw-r--r--engines/groovie/font.h6
-rw-r--r--engines/hopkins/configure.engine3
-rw-r--r--engines/hugo/configure.engine3
-rw-r--r--engines/kyra/configure.engine5
-rw-r--r--engines/lastexpress/configure.engine3
-rw-r--r--engines/lure/configure.engine3
-rw-r--r--engines/made/configure.engine3
-rw-r--r--engines/mohawk/configure.engine6
-rw-r--r--engines/mortevielle/configure.engine3
-rw-r--r--engines/neverhood/configure.engine3
-rw-r--r--engines/parallaction/configure.engine3
-rw-r--r--engines/pegasus/configure.engine3
-rw-r--r--engines/plugins_table.h130
-rw-r--r--engines/queen/configure.engine3
-rw-r--r--engines/saga/configure.engine5
-rw-r--r--engines/sci/configure.engine4
-rw-r--r--engines/scumm/configure.engine5
-rw-r--r--engines/sky/configure.engine3
-rw-r--r--engines/sword1/configure.engine3
-rw-r--r--engines/sword2/configure.engine3
-rw-r--r--engines/sword25/configure.engine3
-rw-r--r--engines/teenagent/configure.engine3
-rw-r--r--engines/testbed/configure.engine3
-rw-r--r--engines/tinsel/configure.engine3
-rw-r--r--engines/toltecs/configure.engine3
-rw-r--r--engines/tony/configure.engine3
-rw-r--r--engines/toon/configure.engine3
-rw-r--r--engines/touche/configure.engine3
-rw-r--r--engines/tsage/configure.engine3
-rw-r--r--engines/tucker/configure.engine3
-rw-r--r--engines/wintermute/base/font/base_font_truetype.cpp23
-rw-r--r--engines/wintermute/base/font/base_font_truetype.h3
-rw-r--r--engines/wintermute/base/scriptables/script_ext_string.cpp18
-rw-r--r--engines/wintermute/configure.engine3
-rw-r--r--engines/wintermute/dctypes.h3
-rw-r--r--engines/wintermute/utils/string_util.cpp247
-rw-r--r--engines/wintermute/utils/string_util.h5
-rw-r--r--engines/zvision/configure.engine3
-rw-r--r--graphics/font.cpp217
-rw-r--r--graphics/font.h10
-rw-r--r--graphics/fonts/bdf.cpp8
-rw-r--r--graphics/fonts/bdf.h6
-rw-r--r--graphics/fonts/ttf.cpp81
-rw-r--r--graphics/fonts/winfont.cpp6
-rw-r--r--graphics/fonts/winfont.h6
-rw-r--r--ports.mk10
77 files changed, 1292 insertions, 887 deletions
diff --git a/.gitignore b/.gitignore
index 0fe212098c..469f22d11c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -105,6 +105,9 @@ project.xcworkspace
/plugins
+/engines/plugins_table.h
+/engines/engines.mk
+
/test/runner
/test/runner.cpp
/test/*.dSYM
diff --git a/Makefile b/Makefile
index 09c38b2598..88b60ca73f 100644
--- a/Makefile
+++ b/Makefile
@@ -82,7 +82,8 @@ EXECUTABLE := $(EXEPRE)scummvm$(EXEEXT)
include $(srcdir)/Makefile.common
# check if configure has been run or has been changed since last run
-config.h config.mk: $(srcdir)/configure $(srcdir)/engines/configure.engines
+ENGINE_SUBDIRS_CONFIGURE := $(wildcard $(srcdir)/engines/*/configure.engine)
+config.h: $(srcdir)/configure $(ENGINE_SUBDIRS_CONFIGURE)
ifeq "$(findstring config.mk,$(MAKEFILE_LIST))" "config.mk"
@echo "Running $(srcdir)/configure with the last specified parameters"
@sleep 2
@@ -94,6 +95,14 @@ else
$(error You need to run $(srcdir)/configure before you can run make. Check $(srcdir)/configure --help for a list of parameters)
endif
+config.mk engines/plugins_table.h engines/engines.mk: config.h
+ @if test -f $@; then \
+ touch $@; \
+ else \
+ rm -f config.h; \
+ $(MAKE) config.h; \
+ fi
+
ifneq ($(origin port_mk), undefined)
include $(srcdir)/$(port_mk)
endif
diff --git a/Makefile.common b/Makefile.common
index 02c3408684..b56300a115 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -16,7 +16,7 @@ all: $(EXECUTABLE) plugins
PLUGINS :=
MODULES := test devtools base $(MODULES)
--include $(srcdir)/engines/engines.mk
+-include engines/engines.mk
# After the game specific modules follow the shared modules
MODULES += \
@@ -79,7 +79,7 @@ $(EXECUTABLE): $(OBJS)
$(QUIET_LINK)$(LD) $(LDFLAGS) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) -o $@
distclean: clean clean-devtools
- $(RM) config.h config.mk config.log
+ $(RM) config.h config.mk config.log engines/engines.mk engines/plugins_table.h
clean:
$(RM_REC) $(DEPDIRS)
@@ -147,7 +147,7 @@ endif
# recreate them (which it can't), and in particular from looking for potential
# source files. This can save quite a bit of disk access time.
.PHONY: $(wildcard $(addsuffix /*.d,$(DEPDIRS))) $(addprefix $(srcdir)/, $(addsuffix /module.mk,$(MODULES))) \
- $(srcdir)/$(port_mk) $(srcdir)/rules.mk $(srcdir)/engines/engines.mk
+ $(srcdir)/$(port_mk) $(srcdir)/rules.mk
######################################################################
# Get the current version information
diff --git a/common/module.mk b/common/module.mk
index 1b34d151d0..67c498df00 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -35,6 +35,7 @@ MODULE_OBJS := \
translation.o \
unarj.o \
unzip.o \
+ ustr.o \
util.o \
winexe.o \
winexe_ne.o \
diff --git a/common/str.h b/common/str.h
index 6b4475e1c4..ea2db1d1d6 100644
--- a/common/str.h
+++ b/common/str.h
@@ -234,6 +234,13 @@ public:
static String vformat(const char *fmt, va_list args);
public:
+ typedef char value_type;
+ /**
+ * Unsigned version of the underlying type. This can be used to cast
+ * individual string characters to bigger integer types without sign
+ * extension happening.
+ */
+ typedef unsigned char unsigned_type;
typedef char * iterator;
typedef const char * const_iterator;
diff --git a/common/ustr.cpp b/common/ustr.cpp
new file mode 100644
index 0000000000..fbc831cb56
--- /dev/null
+++ b/common/ustr.cpp
@@ -0,0 +1,329 @@
+/* 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/ustr.h"
+#include "common/memorypool.h"
+#include "common/util.h"
+
+namespace Common {
+
+extern MemoryPool *g_refCountPool;
+
+static uint32 computeCapacity(uint32 len) {
+ // By default, for the capacity we use the next multiple of 32
+ return ((len + 32 - 1) & ~0x1F);
+}
+
+U32String::U32String(const value_type *str) : _size(0), _str(_storage) {
+ if (str == 0) {
+ _storage[0] = 0;
+ _size = 0;
+ } else {
+ uint32 len = 0;
+ const value_type *s = str;
+ while (*s++) {
+ ++len;
+ }
+ initWithCStr(str, len);
+ }
+}
+
+U32String::U32String(const value_type *str, uint32 len) : _size(0), _str(_storage) {
+ initWithCStr(str, len);
+}
+
+U32String::U32String(const value_type *beginP, const value_type *endP) : _size(0), _str(_storage) {
+ assert(endP >= beginP);
+ initWithCStr(beginP, endP - beginP);
+}
+
+U32String::U32String(const U32String &str)
+ : _size(str._size) {
+ if (str.isStorageIntern()) {
+ // String in internal storage: just copy it
+ memcpy(_storage, str._storage, _builtinCapacity * sizeof(value_type));
+ _str = _storage;
+ } else {
+ // String in external storage: use refcount mechanism
+ str.incRefCount();
+ _extern._refCount = str._extern._refCount;
+ _extern._capacity = str._extern._capacity;
+ _str = str._str;
+ }
+ assert(_str != 0);
+}
+
+U32String::~U32String() {
+ decRefCount(_extern._refCount);
+}
+
+U32String &U32String::operator=(const U32String &str) {
+ if (&str == this)
+ return *this;
+
+ if (str.isStorageIntern()) {
+ decRefCount(_extern._refCount);
+ _size = str._size;
+ _str = _storage;
+ memcpy(_str, str._str, (_size + 1) * sizeof(value_type));
+ } else {
+ str.incRefCount();
+ decRefCount(_extern._refCount);
+
+ _extern._refCount = str._extern._refCount;
+ _extern._capacity = str._extern._capacity;
+ _size = str._size;
+ _str = str._str;
+ }
+
+ return *this;
+}
+
+U32String &U32String::operator+=(const U32String &str) {
+ if (&str == this) {
+ return operator+=(U32String(str));
+ }
+
+ int len = str._size;
+ if (len > 0) {
+ ensureCapacity(_size + len, true);
+
+ memcpy(_str + _size, str._str, (len + 1) * sizeof(value_type));
+ _size += len;
+ }
+ return *this;
+}
+
+U32String &U32String::operator+=(value_type c) {
+ ensureCapacity(_size + 1, true);
+
+ _str[_size++] = c;
+ _str[_size] = 0;
+
+ return *this;
+}
+
+bool U32String::equals(const U32String &x) const {
+ if (this == &x || _str == x._str) {
+ return true;
+ }
+
+ if (x.size() != _size) {
+ return false;
+ }
+
+ return !memcmp(_str, x._str, _size * sizeof(value_type));
+}
+
+bool U32String::contains(value_type x) const {
+ for (uint32 i = 0; i < _size; ++i) {
+ if (_str[i] == x) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void U32String::deleteChar(uint32 p) {
+ assert(p < _size);
+
+ makeUnique();
+ while (p++ < _size)
+ _str[p - 1] = _str[p];
+ _size--;
+}
+
+void U32String::clear() {
+ decRefCount(_extern._refCount);
+
+ _size = 0;
+ _str = _storage;
+ _storage[0] = 0;
+}
+
+void U32String::toLowercase() {
+ makeUnique();
+ for (uint32 i = 0; i < _size; ++i) {
+ if (_str[i] < 128) {
+ _str[i] = tolower(_str[i]);
+ }
+ }
+}
+
+void U32String::toUppercase() {
+ makeUnique();
+ for (uint32 i = 0; i < _size; ++i) {
+ if (_str[i] < 128) {
+ _str[i] = toupper(_str[i]);
+ }
+ }
+}
+
+uint32 U32String::find(const U32String &str, uint32 pos) const {
+ if (pos >= _size) {
+ return npos;
+ }
+
+ const value_type *strP = str.c_str();
+
+ for (const_iterator cur = begin() + pos; *cur; ++cur) {
+ uint i = 0;
+ while (true) {
+ if (!strP[i]) {
+ return cur - begin();
+ }
+
+ if (cur[i] != strP[i]) {
+ break;
+ }
+
+ ++i;
+ }
+ }
+
+ return npos;
+}
+
+void U32String::makeUnique() {
+ ensureCapacity(_size, true);
+}
+
+void U32String::ensureCapacity(uint32 new_size, bool keep_old) {
+ bool isShared;
+ uint32 curCapacity, newCapacity;
+ value_type *newStorage;
+ int *oldRefCount = _extern._refCount;
+
+ if (isStorageIntern()) {
+ isShared = false;
+ curCapacity = _builtinCapacity;
+ } else {
+ isShared = (oldRefCount && *oldRefCount > 1);
+ curCapacity = _extern._capacity;
+ }
+
+ // Special case: If there is enough space, and we do not share
+ // the storage, then there is nothing to do.
+ if (!isShared && new_size < curCapacity)
+ return;
+
+ if (isShared && new_size < _builtinCapacity) {
+ // We share the storage, but there is enough internal storage: Use that.
+ newStorage = _storage;
+ newCapacity = _builtinCapacity;
+ } else {
+ // We need to allocate storage on the heap!
+
+ // Compute a suitable new capacity limit
+ // If the current capacity is sufficient we use the same capacity
+ if (new_size < curCapacity)
+ newCapacity = curCapacity;
+ else
+ newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1));
+
+ // Allocate new storage
+ newStorage = new value_type[newCapacity];
+ assert(newStorage);
+ }
+
+ // Copy old data if needed, elsewise reset the new storage.
+ if (keep_old) {
+ assert(_size < newCapacity);
+ memcpy(newStorage, _str, (_size + 1) * sizeof(value_type));
+ } else {
+ _size = 0;
+ newStorage[0] = 0;
+ }
+
+ // Release hold on the old storage ...
+ decRefCount(oldRefCount);
+
+ // ... in favor of the new storage
+ _str = newStorage;
+
+ if (!isStorageIntern()) {
+ // Set the ref count & capacity if we use an external storage.
+ // It is important to do this *after* copying any old content,
+ // else we would override data that has not yet been copied!
+ _extern._refCount = 0;
+ _extern._capacity = newCapacity;
+ }
+}
+
+void U32String::incRefCount() const {
+ assert(!isStorageIntern());
+ if (_extern._refCount == 0) {
+ if (g_refCountPool == 0) {
+ g_refCountPool = new MemoryPool(sizeof(int));
+ assert(g_refCountPool);
+ }
+
+ _extern._refCount = (int *)g_refCountPool->allocChunk();
+ *_extern._refCount = 2;
+ } else {
+ ++(*_extern._refCount);
+ }
+}
+
+void U32String::decRefCount(int *oldRefCount) {
+ if (isStorageIntern())
+ return;
+
+ if (oldRefCount) {
+ --(*oldRefCount);
+ }
+ if (!oldRefCount || *oldRefCount <= 0) {
+ // The ref count reached zero, so we free the string storage
+ // and the ref count storage.
+ if (oldRefCount) {
+ assert(g_refCountPool);
+ g_refCountPool->freeChunk(oldRefCount);
+ }
+ delete[] _str;
+
+ // Even though _str points to a freed memory block now,
+ // we do not change its value, because any code that calls
+ // decRefCount will have to do this afterwards anyway.
+ }
+}
+
+void U32String::initWithCStr(const value_type *str, uint32 len) {
+ assert(str);
+
+ _storage[0] = 0;
+
+ _size = len;
+
+ if (len >= _builtinCapacity) {
+ // Not enough internal storage, so allocate more
+ _extern._capacity = computeCapacity(len+1);
+ _extern._refCount = 0;
+ _str = new value_type[_extern._capacity];
+ assert(_str != 0);
+ }
+
+ // Copy the string into the storage area
+ memmove(_str, str, len * sizeof(value_type));
+ _str[len] = 0;
+}
+
+} // End of namespace Common
diff --git a/common/ustr.h b/common/ustr.h
new file mode 100644
index 0000000000..ab9dac70de
--- /dev/null
+++ b/common/ustr.h
@@ -0,0 +1,194 @@
+/* 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_USTR_H
+#define COMMON_USTR_H
+
+#include "common/scummsys.h"
+
+namespace Common {
+
+/**
+ * Very simple string class for UTF-32 strings in ScummVM. The main intention
+ * behind this class is to feature a simple way of displaying UTF-32 strings
+ * through the Graphics::Font API.
+ *
+ * Please note that operations like equals, deleteCharacter, toUppercase, etc.
+ * are only very simplified convenience operations. They might not fully work
+ * as you would expect for a proper UTF-32 string class.
+ *
+ * The presence of \0 characters in the string will cause undefined
+ * behavior in some operations.
+ */
+class U32String {
+public:
+ static const uint32 npos = 0xFFFFFFFF;
+
+ typedef uint32 value_type;
+ typedef uint32 unsigned_type;
+private:
+ /**
+ * The size of the internal storage. Increasing this means less heap
+ * allocations are needed, at the cost of more stack memory usage,
+ * and of course lots of wasted memory.
+ */
+ static const uint32 _builtinCapacity = 32;
+
+ /**
+ * Length of the string.
+ */
+ uint32 _size;
+
+ /**
+ * Pointer to the actual string storage. Either points to _storage,
+ * or to a block allocated on the heap via malloc.
+ */
+ value_type *_str;
+
+
+ union {
+ /**
+ * Internal string storage.
+ */
+ value_type _storage[_builtinCapacity];
+ /**
+ * External string storage data -- the refcounter, and the
+ * capacity of the string _str points to.
+ */
+ struct {
+ mutable int *_refCount;
+ uint32 _capacity;
+ } _extern;
+ };
+
+ inline bool isStorageIntern() const {
+ return _str == _storage;
+ }
+
+public:
+ /** Construct a new empty string. */
+ U32String() : _size(0), _str(_storage) { _storage[0] = 0; }
+
+ /** Construct a new string from the given NULL-terminated C string. */
+ explicit U32String(const value_type *str);
+
+ /** Construct a new string containing exactly len characters read from address str. */
+ U32String(const value_type *str, uint32 len);
+
+ /** Construct a new string containing the characters between beginP (including) and endP (excluding). */
+ U32String(const value_type *beginP, const value_type *endP);
+
+ /** Construct a copy of the given string. */
+ U32String(const U32String &str);
+
+ ~U32String();
+
+ U32String &operator=(const U32String &str);
+ U32String &operator+=(const U32String &str);
+ U32String &operator+=(value_type c);
+
+ /**
+ * Equivalence comparison operator.
+ * @see equals
+ */
+ bool operator==(const U32String &x) const { return equals(x); }
+
+ /**
+ * Compares whether two U32String are the same based on memory comparison.
+ * This does *not* do comparison based on canonical equivalence.
+ */
+ bool equals(const U32String &x) const;
+
+ bool contains(value_type x) const;
+
+ inline const value_type *c_str() const { return _str; }
+ inline uint32 size() const { return _size; }
+
+ inline bool empty() const { return (_size == 0); }
+
+ value_type operator[](int idx) const {
+ assert(_str && idx >= 0 && idx < (int)_size);
+ return _str[idx];
+ }
+
+ /**
+ * Removes the value at position p from the string.
+ * Using this on decomposed characters will not remove the whole
+ * character!
+ */
+ void deleteChar(uint32 p);
+
+ /** Clears the string, making it empty. */
+ void clear();
+
+ /**
+ * Convert all characters in the string to lowercase.
+ *
+ * Be aware that this only affects the case of ASCII characters. All
+ * other characters will not be touched at all.
+ */
+ void toLowercase();
+
+ /**
+ * Convert all characters in the string to uppercase.
+ *
+ * Be aware that this only affects the case of ASCII characters. All
+ * other characters will not be touched at all.
+ */
+ void toUppercase();
+
+ uint32 find(const U32String &str, uint32 pos = 0) const;
+
+ typedef value_type * iterator;
+ typedef const value_type * const_iterator;
+
+ iterator begin() {
+ // Since the user could potentially
+ // change the string via the returned
+ // iterator we have to assure we are
+ // pointing to a unique storage.
+ makeUnique();
+
+ return _str;
+ }
+
+ iterator end() {
+ return begin() + size();
+ }
+
+ const_iterator begin() const {
+ return _str;
+ }
+
+ const_iterator end() const {
+ return begin() + size();
+ }
+private:
+ void makeUnique();
+ void ensureCapacity(uint32 new_size, bool keep_old);
+ void incRefCount() const;
+ void decRefCount(int *oldRefCount);
+ void initWithCStr(const value_type *str, uint32 len);
+};
+
+} // End of namespace Common
+
+#endif
diff --git a/configure b/configure
index cb0b8902fc..d454591f08 100755
--- a/configure
+++ b/configure
@@ -97,7 +97,9 @@ add_feature() {
_srcdir=`dirname $0`
# Read list of engines
-. $_srcdir/engines/configure.engines
+for i in $_srcdir/engines/*/configure.engine; do
+ . "$i"
+done
#
# Default settings
@@ -4197,8 +4199,18 @@ for engine in $_engines; do
fi
done
-# Prepare the information to be shown
+# Sort engines to place our headline engine at start...
+# No technical reason, just historical convention
+headline_engine=scumm
+_sorted_engines="${headline_engine}"
for engine in $_engines; do
+ if test "${engine}" != "${headline_engine}" ; then
+ _sorted_engines="${_sorted_engines} ${engine}"
+ fi
+done
+
+# Prepare the information to be shown
+for engine in $_sorted_engines; do
if test "`get_engine_sub $engine`" = "no" ; then
# It's a main engine
prepare_engine_build_strings $engine
@@ -4380,3 +4392,59 @@ include \$(srcdir)/Makefile
EOF
fi
+
+# Ensure engines folder exists prior to trying to generate
+# files into it (used for out-of-tree-builds)
+mkdir -p engines
+
+echo "Creating engines/engines.mk"
+cat > engines/engines.mk << EOF
+# This file is automatically generated by configure
+# DO NOT EDIT MANUALLY
+# This file is being included by "Makefile.common"
+EOF
+
+for engine in $_sorted_engines; do
+ j=`echo $engine | tr '[:lower:]' '[:upper:]'`
+ if test "`get_engine_sub $engine`" = "no" ; then
+ # main engine
+ cat >> engines/engines.mk << EOF
+
+ifdef ENABLE_$j
+DEFINES += -DENABLE_$j=\$(ENABLE_$j)
+MODULES += engines/$engine
+EOF
+
+ for subeng in `get_engine_subengines $engine` ; do
+ k=`echo $subeng | tr '[:lower:]' '[:upper:]'`
+ cat >> engines/engines.mk << EOF
+
+ifdef ENABLE_$k
+DEFINES += -DENABLE_$k
+endif
+EOF
+ done
+
+ cat >> engines/engines.mk << EOF
+endif
+EOF
+ fi
+done
+
+echo "Creating engines/plugins_table.h"
+cat > engines/plugins_table.h << EOF
+/* This file is automatically generated by configure */
+/* DO NOT EDIT MANUALLY */
+// This file is being included by "base/plugins.cpp"
+EOF
+
+for engine in $_sorted_engines; do
+ if test "`get_engine_sub $engine`" = "no" ; then
+ j=`echo $engine | tr '[:lower:]' '[:upper:]'`
+ cat >> engines/plugins_table.h << EOF
+#if PLUGIN_ENABLED_STATIC($j)
+LINK_PLUGIN($j)
+#endif
+EOF
+ fi
+done
diff --git a/devtools/create_project/codeblocks.cpp b/devtools/create_project/codeblocks.cpp
index ec003df2d5..442a2b0025 100644
--- a/devtools/create_project/codeblocks.cpp
+++ b/devtools/create_project/codeblocks.cpp
@@ -120,6 +120,7 @@ void CodeBlocksProvider::createProjectFile(const std::string &name, const std::s
"\t\t\t\t\t<Add directory=\"..\\..\\engines\" />\n"
"\t\t\t\t\t<Add directory=\"..\\..\\common\" />\n"
"\t\t\t\t\t<Add directory=\"..\\..\" />\n"
+ "\t\t\t\t\t<Add directory=\".\\\" />\n"
"\t\t\t\t</Compiler>\n";
//////////////////////////////////////////////////////////////////////////
diff --git a/devtools/create_project/config.h b/devtools/create_project/config.h
index 1a66edff93..9d4b101360 100644
--- a/devtools/create_project/config.h
+++ b/devtools/create_project/config.h
@@ -27,6 +27,7 @@
#define PROJECT_NAME "scummvm" // Used for folders, icons, resources and project/solution name
#define LIBS_DEFINE "SCUMMVM_LIBS" // Name of the include environment variable
#define REVISION_DEFINE "SCUMMVM_INTERNAL_REVISION"
+#define FIRST_ENGINE "scumm" // Name of the engine which should be sorted as first element
#define ENABLE_LANGUAGE_EXTENSIONS "" // Comma separated list of projects that need language extensions
#define DISABLE_EDIT_AND_CONTINUE "tinsel,tony,scummvm" // Comma separated list of projects that need Edit&Continue to be disabled for co-routine support (the main project is automatically added)
diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp
index e013377241..16b8e1d166 100644
--- a/devtools/create_project/create_project.cpp
+++ b/devtools/create_project/create_project.cpp
@@ -59,6 +59,7 @@
#include <sys/param.h>
#include <sys/stat.h>
#include <dirent.h>
+#include <errno.h>
#endif
namespace {
@@ -81,22 +82,6 @@ std::string unifyPath(const std::string &path);
* @param exe Name of the executable.
*/
void displayHelp(const char *exe);
-
-/**
- * Structure for describing an FSNode. This is a very minimalistic
- * description, which includes everything we need.
- * It only contains the name of the node and whether it is a directory
- * or not.
- */
-struct FSNode {
- FSNode() : name(), isDirectory(false) {}
- FSNode(const std::string &n, bool iD) : name(n), isDirectory(iD) {}
-
- std::string name; ///< Name of the file system node
- bool isDirectory; ///< Whether it is a directory or not
-};
-
-typedef std::list<FSNode> FileList;
} // End of anonymous namespace
enum ProjectType {
@@ -128,7 +113,7 @@ int main(int argc, char *argv[]) {
setup.filePrefix = setup.srcDir;
setup.outputDir = '.';
- setup.engines = parseConfigure(setup.srcDir);
+ setup.engines = parseEngines(setup.srcDir);
if (setup.engines.empty()) {
std::cout << "WARNING: No engines found in configure file or configure file missing in \"" << setup.srcDir << "\"\n";
@@ -672,47 +657,70 @@ void displayHelp(const char *exe) {
}
/**
- * Try to parse a given line and create an engine definition
- * out of the result.
+ * Parse the configure.engine file of a given engine directory and return a
+ * list of all defined engines.
*
- * This may take *any* input line, when the line is not used
- * to define an engine the result of the function will be "false".
+ * @param engineDir The directory of the engine.
+ * @return The list of all defined engines.
+ */
+EngineDescList parseEngineConfigure(const std::string &engineDir);
+
+/**
+ * Compares two FSNode entries in a strict-weak fashion based on the name.
*
- * Note that the contents of "engine" are undefined, when this
- * function returns "false".
+ * @param left The first operand.
+ * @param right The second operand.
+ * @return "true" when the name of the left operand is strictly smaller than
+ * the name of the second operand. "false" otherwise.
+ */
+bool compareFSNode(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right);
+
+#ifdef FIRST_ENGINE
+/**
+ * Compares two FSNode entries in a strict-weak fashion based on engine name
+ * order.
*
- * @param line Text input line.
- * @param engine Reference to an object, where the engine information
- * is to be stored in.
- * @return "true", when parsing succeeded, "false" otherwise.
+ * @param left The first operand.
+ * @param right The second operand.
+ * @return "true" when the name of the left operand is strictly smaller than
+ * the name of the second operand. "false" otherwise.
*/
-bool parseEngine(const std::string &line, EngineDesc &engine);
+bool compareEngineNames(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right);
+#endif
} // End of anonymous namespace
-EngineDescList parseConfigure(const std::string &srcDir) {
- std::string configureFile = srcDir + "/engines/configure.engines";
+EngineDescList parseEngines(const std::string &srcDir) {
+ using CreateProjectTool::FileList;
+ using CreateProjectTool::listDirectory;
- std::ifstream configure(configureFile.c_str());
- if (!configure)
- return EngineDescList();
+ EngineDescList engineList;
- std::string line;
- EngineDescList engines;
+ FileList engineFiles = listDirectory(srcDir + "/engines/");
- for (;;) {
- std::getline(configure, line);
- if (configure.eof())
- break;
+#ifdef FIRST_ENGINE
+ // In case we want to sort an engine to the front of the list we will
+ // use some manual sorting predicate which assures that.
+ engineFiles.sort(&compareEngineNames);
+#else
+ // Otherwise, we simply sort the file list alphabetically this allows
+ // for a nicer order in --list-engines output, for example.
+ engineFiles.sort(&compareFSNode);
+#endif
- if (configure.fail())
- error("Failed while reading from " + configureFile);
+ for (FileList::const_iterator i = engineFiles.begin(), end = engineFiles.end(); i != end; ++i) {
+ // Each engine requires its own sub directory thus we will skip all
+ // non directory file nodes here.
+ if (!i->isDirectory) {
+ continue;
+ }
- EngineDesc desc;
- if (parseEngine(line, desc))
- engines.push_back(desc);
+ // Retrieve all engines defined in this sub directory and add them to
+ // the list of all engines.
+ EngineDescList list = parseEngineConfigure(srcDir + "/engines/" + i->name);
+ engineList.splice(engineList.end(), list);
}
- return engines;
+ return engineList;
}
bool isSubEngine(const std::string &name, const EngineDescList &engines) {
@@ -777,6 +785,21 @@ StringList getEngineDefines(const EngineDescList &engines) {
}
namespace {
+/**
+ * Try to parse a given line and create an engine definition
+ * out of the result.
+ *
+ * This may take *any* input line, when the line is not used
+ * to define an engine the result of the function will be "false".
+ *
+ * Note that the contents of "engine" are undefined, when this
+ * function returns "false".
+ *
+ * @param line Text input line.
+ * @param engine Reference to an object, where the engine information
+ * is to be stored in.
+ * @return "true", when parsing succeeded, "false" otherwise.
+ */
bool parseEngine(const std::string &line, EngineDesc &engine) {
// Format:
// add_engine engine_name "Readable Description" enable_default ["SubEngineList"]
@@ -799,6 +822,48 @@ bool parseEngine(const std::string &line, EngineDesc &engine) {
return true;
}
+
+EngineDescList parseEngineConfigure(const std::string &engineDir) {
+ std::string configureFile = engineDir + "/configure.engine";
+
+ std::ifstream configure(configureFile.c_str());
+ if (!configure)
+ return EngineDescList();
+
+ std::string line;
+ EngineDescList engines;
+
+ for (;;) {
+ std::getline(configure, line);
+ if (configure.eof())
+ break;
+
+ if (configure.fail())
+ error("Failed while reading from " + configureFile);
+
+ EngineDesc desc;
+ if (parseEngine(line, desc))
+ engines.push_back(desc);
+ }
+
+ return engines;
+}
+
+bool compareFSNode(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right) {
+ return left.name < right.name;
+}
+
+#ifdef FIRST_ENGINE
+bool compareEngineNames(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right) {
+ if (left.name == FIRST_ENGINE) {
+ return right.name != FIRST_ENGINE;
+ } else if (right.name == FIRST_ENGINE) {
+ return false;
+ } else {
+ return compareFSNode(left, right);
+ }
+}
+#endif
} // End of anonymous namespace
TokenList tokenize(const std::string &input, char separator) {
@@ -1048,13 +1113,6 @@ bool compareNodes(const FileNode *l, const FileNode *r) {
}
}
-/**
- * Returns a list of all files and directories in the specified
- * path.
- *
- * @param dir Directory which should be listed.
- * @return List of all children.
- */
FileList listDirectory(const std::string &dir) {
FileList result;
#ifdef USE_WIN32_API
@@ -1095,6 +1153,32 @@ FileList listDirectory(const std::string &dir) {
return result;
}
+void createDirectory(const std::string &dir) {
+#if defined(_WIN32) || defined(WIN32)
+ if (!CreateDirectory(dir.c_str(), NULL)) {
+ if (GetLastError() != ERROR_ALREADY_EXISTS) {
+ error("Could not create folder \"" + dir + "\"");
+ }
+ }
+#else
+ if (mkdir(dir.c_str(), 0777) == -1) {
+ if (errno == EEXIST) {
+ // Try to open as a folder (might be a file / symbolic link)
+ DIR *dirp = opendir(dir.c_str());
+ if (dirp == NULL) {
+ error("Could not create folder \"" + dir + "\"");
+ } else {
+ // The folder exists, just close the stream and return
+ closedir(dirp);
+ }
+ } else {
+ error("Could not create folder \"" + dir + "\"");
+ }
+ }
+#endif
+
+}
+
/**
* Scans the specified directory against files, which should be included
* in the project files. It will not include files present in the exclude list.
@@ -1242,6 +1326,12 @@ void ProjectProvider::createProject(BuildSetup &setup) {
// Create other misc. build files
createOtherBuildFiles(setup);
+
+ // In case we create the main ScummVM project files we will need to
+ // generate engines/plugins_table.h too.
+ if (!setup.tests && !setup.devTools) {
+ createEnginePluginsTable(setup);
+ }
}
ProjectProvider::UUIDMap ProjectProvider::createUUIDMap(const BuildSetup &setup) const {
@@ -1569,6 +1659,37 @@ void ProjectProvider::createModuleList(const std::string &moduleDir, const Strin
error("Malformed file " + moduleMkFile);
}
+void ProjectProvider::createEnginePluginsTable(const BuildSetup &setup) {
+ // First we need to create the "engines" directory.
+ createDirectory(setup.outputDir + "/engines");
+
+ // Then, we can generate the actual "plugins_table.h" file.
+ const std::string enginePluginsTableFile = setup.outputDir + "/engines/plugins_table.h";
+ std::ofstream enginePluginsTable(enginePluginsTableFile.c_str());
+ if (!enginePluginsTable) {
+ error("Could not open \"" + enginePluginsTableFile + "\" for writing");
+ }
+
+ enginePluginsTable << "/* This file is automatically generated by create_project */\n"
+ << "/* DO NOT EDIT MANUALLY */\n"
+ << "// This file is being included by \"base/plugins.cpp\"\n";
+
+ for (EngineDescList::const_iterator i = setup.engines.begin(), end = setup.engines.end(); i != end; ++i) {
+ // We ignore all sub engines here because they require no special
+ // handling.
+ if (isSubEngine(i->name, setup.engines)) {
+ continue;
+ }
+
+ // Make the engine name all uppercase.
+ std::string engineName;
+ std::transform(i->name.begin(), i->name.end(), std::back_inserter(engineName), toupper);
+
+ enginePluginsTable << "#if PLUGIN_ENABLED_STATIC(" << engineName << ")\n"
+ << "LINK_PLUGIN(" << engineName << ")\n"
+ << "#endif\n";
+ }
+}
} // End of anonymous namespace
void error(const std::string &message) {
diff --git a/devtools/create_project/create_project.h b/devtools/create_project/create_project.h
index 2f27cc2f61..459342a67d 100644
--- a/devtools/create_project/create_project.h
+++ b/devtools/create_project/create_project.h
@@ -102,16 +102,17 @@ struct EngineDesc {
typedef std::list<EngineDesc> EngineDescList;
/**
- * This function parses the project configure file and creates a list
- * of available engines.
+ * This function parses the project directory and creates a list of
+ * available engines.
*
* It will also automatically setup the default build state (enabled
- * or disabled) to the state specified in the "configure" file.
+ * or disabled) to the state specified in the individual configure.engine
+ * files.
*
* @param srcDir Path to the root of the project source.
* @return List of available engines.
*/
-EngineDescList parseConfigure(const std::string &srcDir);
+EngineDescList parseEngines(const std::string &srcDir);
/**
* Checks whether the specified engine is a sub engine. To determine this
@@ -263,6 +264,22 @@ void NORETURN_PRE error(const std::string &message) NORETURN_POST;
namespace CreateProjectTool {
/**
+ * Structure for describing an FSNode. This is a very minimalistic
+ * description, which includes everything we need.
+ * It only contains the name of the node and whether it is a directory
+ * or not.
+ */
+struct FSNode {
+ FSNode() : name(), isDirectory(false) {}
+ FSNode(const std::string &n, bool iD) : name(n), isDirectory(iD) {}
+
+ std::string name; ///< Name of the file system node
+ bool isDirectory; ///< Whether it is a directory or not
+};
+
+typedef std::list<FSNode> FileList;
+
+/**
* Gets a proper sequence of \t characters for the given
* indentation level.
*
@@ -315,6 +332,22 @@ bool producesObjectFile(const std::string &fileName);
std::string toString(int num);
/**
+ * Returns a list of all files and directories in the specified
+ * path.
+ *
+ * @param dir Directory which should be listed.
+ * @return List of all children.
+ */
+FileList listDirectory(const std::string &dir);
+
+/**
+ * Create a directory at the given path.
+ *
+ * @param dir The path to create.
+ */
+void createDirectory(const std::string &dir);
+
+/**
* Structure representing a file tree. This contains two
* members: name and children. "name" holds the name of
* the node. "children" does contain all the node's children.
@@ -474,6 +507,15 @@ protected:
* @return A new UUID as string.
*/
std::string createUUID() const;
+
+private:
+ /**
+ * This creates the engines/plugins_table.h file required for building
+ * ScummVM.
+ *
+ * @param setup Description of the desired build.
+ */
+ void createEnginePluginsTable(const BuildSetup &setup);
};
} // End of CreateProjectTool namespace
diff --git a/devtools/create_project/msbuild.cpp b/devtools/create_project/msbuild.cpp
index 0d68b2e9c9..07ae20e7dc 100644
--- a/devtools/create_project/msbuild.cpp
+++ b/devtools/create_project/msbuild.cpp
@@ -360,7 +360,7 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea
"\t\t<ClCompile>\n"
"\t\t\t<DisableLanguageExtensions>true</DisableLanguageExtensions>\n"
"\t\t\t<DisableSpecificWarnings>" << warnings << ";%(DisableSpecificWarnings)</DisableSpecificWarnings>\n"
- "\t\t\t<AdditionalIncludeDirectories>$(" << LIBS_DEFINE << ")\\include;" << prefix << ";" << prefix << "\\engines;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n"
+ "\t\t\t<AdditionalIncludeDirectories>$(" << LIBS_DEFINE << ")\\include;.\\;" << prefix << ";" << prefix << "\\engines;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n"
"\t\t\t<PreprocessorDefinitions>" << definesList << "%(PreprocessorDefinitions)</PreprocessorDefinitions>\n"
"\t\t\t<ExceptionHandling>" << ((setup.devTools || setup.tests) ? "Sync" : "") << "</ExceptionHandling>\n";
diff --git a/devtools/create_project/visualstudio.cpp b/devtools/create_project/visualstudio.cpp
index 438e0772f9..84bc674f9a 100644
--- a/devtools/create_project/visualstudio.cpp
+++ b/devtools/create_project/visualstudio.cpp
@@ -232,7 +232,7 @@ void VisualStudioProvider::outputGlobalPropFile(const BuildSetup &setup, std::of
"\t\tName=\"VCCLCompilerTool\"\n"
"\t\tDisableLanguageExtensions=\"" << (setup.devTools ? "false" : "true") << "\"\n"
"\t\tDisableSpecificWarnings=\"" << warnings << "\"\n"
- "\t\tAdditionalIncludeDirectories=\"" << prefix << ";" << prefix << "\\engines;$(" << LIBS_DEFINE << ")\\include;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir)\"\n"
+ "\t\tAdditionalIncludeDirectories=\".\\;" << prefix << ";" << prefix << "\\engines;$(" << LIBS_DEFINE << ")\\include;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir)\"\n"
"\t\tPreprocessorDefinitions=\"" << definesList << "\"\n"
"\t\tExceptionHandling=\"" << ((setup.devTools || setup.tests) ? "1" : "0") << "\"\n";
diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp
index a9b8e7a752..d95bf3e9ee 100644
--- a/devtools/create_project/xcode.cpp
+++ b/devtools/create_project/xcode.cpp
@@ -26,15 +26,6 @@
#include <fstream>
#include <algorithm>
-#if defined(_WIN32) || defined(WIN32)
-#include <windows.h>
-#else
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <errno.h>
-#endif
-
namespace CreateProjectTool {
#define DEBUG_XCODE_HASH 0
@@ -88,27 +79,7 @@ XCodeProvider::XCodeProvider(StringList &global_warnings, std::map<std::string,
void XCodeProvider::createWorkspace(const BuildSetup &setup) {
// Create project folder
std::string workspace = setup.outputDir + '/' + PROJECT_NAME ".xcodeproj";
-
-#if defined(_WIN32) || defined(WIN32)
- if (!CreateDirectory(workspace.c_str(), NULL))
- if (GetLastError() != ERROR_ALREADY_EXISTS)
- error("Could not create folder \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj\"");
-#else
- if (mkdir(workspace.c_str(), 0777) == -1) {
- if (errno == EEXIST) {
- // Try to open as a folder (might be a file / symbolic link)
- DIR *dirp = opendir(workspace.c_str());
- if (dirp == NULL) {
- error("Could not create folder \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj\"");
- } else {
- // The folder exists, just close the stream and return
- closedir(dirp);
- }
- } else {
- error("Could not create folder \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj\"");
- }
- }
-#endif
+ createDirectory(workspace);
// Setup global objects
setupDefines(setup);
diff --git a/engines/agi/configure.engine b/engines/agi/configure.engine
new file mode 100644
index 0000000000..fad659f86d
--- /dev/null
+++ b/engines/agi/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine agi "AGI" yes
diff --git a/engines/agos/configure.engine b/engines/agos/configure.engine
new file mode 100644
index 0000000000..3ae1fb16f2
--- /dev/null
+++ b/engines/agos/configure.engine
@@ -0,0 +1,4 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine agos "AGOS" yes "agos2" "AGOS 1 games"
+add_engine agos2 "AGOS 2 games" yes
diff --git a/engines/avalanche/configure.engine b/engines/avalanche/configure.engine
new file mode 100644
index 0000000000..28d6a558db
--- /dev/null
+++ b/engines/avalanche/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine avalanche "Lord Avalot d'Argent" no
diff --git a/engines/cge/configure.engine b/engines/cge/configure.engine
new file mode 100644
index 0000000000..72af1197be
--- /dev/null
+++ b/engines/cge/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine cge "CGE" yes
diff --git a/engines/cine/configure.engine b/engines/cine/configure.engine
new file mode 100644
index 0000000000..2b7e2085fa
--- /dev/null
+++ b/engines/cine/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine cine "Cinematique evo 1" yes
diff --git a/engines/composer/configure.engine b/engines/composer/configure.engine
new file mode 100644
index 0000000000..71a79acb5d
--- /dev/null
+++ b/engines/composer/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine composer "Magic Composer" yes
diff --git a/engines/configure.engines b/engines/configure.engines
deleted file mode 100644
index ec7d4667ca..0000000000
--- a/engines/configure.engines
+++ /dev/null
@@ -1,57 +0,0 @@
-# This file is included from the main "configure" script
-# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine scumm "SCUMM" yes "scumm_7_8 he" "v0-v6 games"
-add_engine scumm_7_8 "v7 & v8 games" yes
-add_engine he "HE71+ games" yes
-add_engine agi "AGI" yes
-add_engine agos "AGOS" yes "agos2" "AGOS 1 games"
-add_engine agos2 "AGOS 2 games" yes
-add_engine avalanche "Lord Avalot d'Argent" no
-add_engine cge "CGE" yes
-add_engine cine "Cinematique evo 1" yes
-add_engine composer "Magic Composer" yes
-add_engine cruise "Cinematique evo 2" yes
-add_engine draci "Dragon History" yes
-add_engine drascula "Drascula: The Vampire Strikes Back" yes
-add_engine dreamweb "Dreamweb" yes
-add_engine fullpipe "Full Pipe" no
-add_engine gob "Gobli*ns" yes
-add_engine groovie "Groovie" yes "groovie2" "7th Guest"
-add_engine groovie2 "Groovie 2 games" no "" "" "jpeg"
-add_engine hopkins "Hopkins FBI" yes "" "" "16bit"
-add_engine hugo "Hugo Trilogy" yes
-add_engine kyra "Kyra" yes "lol eob" "Legend of Kyrandia 1-3"
-add_engine lol "Lands of Lore" yes
-add_engine eob "Eye of the Beholder" yes
-add_engine lastexpress "The Last Express" no "" "" "16bit"
-add_engine lure "Lure of the Temptress" yes
-add_engine made "MADE" yes
-add_engine mohawk "Mohawk" yes "cstime myst riven" "Living Books"
-add_engine mortevielle "Mortevielle" no
-add_engine cstime "Where in Time is Carmen Sandiego?" no
-add_engine riven "Riven: The Sequel to Myst" no "" "" "16bit"
-add_engine myst "Myst" no "" "" "16bit"
-add_engine neverhood "Neverhood" no
-add_engine parallaction "Parallaction" yes
-add_engine pegasus "The Journeyman Project: Pegasus Prime" yes "" "" "16bit"
-add_engine queen "Flight of the Amazon Queen" yes
-add_engine saga "SAGA" yes "ihnm saga2" "ITE"
-add_engine ihnm "IHNM" yes
-add_engine saga2 "SAGA 2 games" no
-add_engine sci "SCI" yes "sci32" "SCI 0-1.1 games"
-add_engine sci32 "SCI32 games" no
-add_engine sky "Beneath a Steel Sky" yes
-add_engine sword1 "Broken Sword" yes
-add_engine sword2 "Broken Sword II" yes
-add_engine sword25 "Broken Sword 2.5" no "" "" "png zlib 16bit"
-add_engine teenagent "Teen Agent" yes
-add_engine testbed "TestBed: the Testing framework" no
-add_engine tinsel "Tinsel" yes
-add_engine toltecs "3 Skulls of the Toltecs" yes
-add_engine toon "Toonstruck" yes
-add_engine touche "Touche: The Adventures of the Fifth Musketeer" yes
-add_engine tony "Tony Tough and the Night of Roasted Moths" yes "" "" "16bit"
-add_engine tsage "TsAGE" yes
-add_engine tucker "Bud Tucker in Double Trouble" yes
-add_engine wintermute "Wintermute" no "" "" "jpeg png zlib vorbis 16bit"
-add_engine zvision "ZVision" no "" "" "freetype2 16bit"
diff --git a/engines/cruise/configure.engine b/engines/cruise/configure.engine
new file mode 100644
index 0000000000..925da25370
--- /dev/null
+++ b/engines/cruise/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine cruise "Cinematique evo 2" yes
diff --git a/engines/draci/configure.engine b/engines/draci/configure.engine
new file mode 100644
index 0000000000..09022b06f5
--- /dev/null
+++ b/engines/draci/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine draci "Dragon History" yes
diff --git a/engines/drascula/configure.engine b/engines/drascula/configure.engine
new file mode 100644
index 0000000000..b9b76638fd
--- /dev/null
+++ b/engines/drascula/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine drascula "Drascula: The Vampire Strikes Back" yes
diff --git a/engines/dreamweb/configure.engine b/engines/dreamweb/configure.engine
new file mode 100644
index 0000000000..27506e650f
--- /dev/null
+++ b/engines/dreamweb/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine dreamweb "Dreamweb" yes
diff --git a/engines/engines.mk b/engines/engines.mk
deleted file mode 100644
index cfde77321d..0000000000
--- a/engines/engines.mk
+++ /dev/null
@@ -1,263 +0,0 @@
-ifdef ENABLE_SCUMM
-DEFINES += -DENABLE_SCUMM=$(ENABLE_SCUMM)
-MODULES += engines/scumm
-
-ifdef ENABLE_SCUMM_7_8
-DEFINES += -DENABLE_SCUMM_7_8
-endif
-
-ifdef ENABLE_HE
-DEFINES += -DENABLE_HE
-endif
-
-endif
-
-ifdef ENABLE_AGI
-DEFINES += -DENABLE_AGI=$(ENABLE_AGI)
-MODULES += engines/agi
-endif
-
-ifdef ENABLE_AGOS
-DEFINES += -DENABLE_AGOS=$(ENABLE_AGOS)
-MODULES += engines/agos
-
-ifdef ENABLE_AGOS2
-DEFINES += -DENABLE_AGOS2
-endif
-endif
-
-ifdef ENABLE_AVALANCHE
-DEFINES += -DENABLE_AVALANCHE=$(ENABLE_AVALANCHE)
-MODULES += engines/avalanche
-endif
-
-ifdef ENABLE_CGE
-DEFINES += -DENABLE_CGE=$(ENABLE_CGE)
-MODULES += engines/cge
-endif
-
-ifdef ENABLE_CINE
-DEFINES += -DENABLE_CINE=$(ENABLE_CINE)
-MODULES += engines/cine
-endif
-
-ifdef ENABLE_COMPOSER
-DEFINES += -DENABLE_COMPOSER=$(ENABLE_COMPOSER)
-MODULES += engines/composer
-endif
-
-ifdef ENABLE_CRUISE
-DEFINES += -DENABLE_CRUISE=$(ENABLE_CRUISE)
-MODULES += engines/cruise
-endif
-
-ifdef ENABLE_DRACI
-DEFINES += -DENABLE_DRACI=$(ENABLE_DRACI)
-MODULES += engines/draci
-endif
-
-ifdef ENABLE_DRASCULA
-DEFINES += -DENABLE_DRASCULA=$(ENABLE_DRASCULA)
-MODULES += engines/drascula
-endif
-
-ifdef ENABLE_DREAMWEB
-DEFINES += -DENABLE_DREAMWEB=$(ENABLE_DREAMWEB)
-MODULES += engines/dreamweb
-endif
-
-ifdef ENABLE_FULLPIPE
-DEFINES += -DENABLE_FULLPIPE=$(ENABLE_FULLPIPE)
-MODULES += engines/fullpipe
-endif
-
-ifdef ENABLE_GOB
-DEFINES += -DENABLE_GOB=$(ENABLE_GOB)
-MODULES += engines/gob
-endif
-
-ifdef ENABLE_GROOVIE
-DEFINES += -DENABLE_GROOVIE=$(ENABLE_GROOVIE)
-MODULES += engines/groovie
-
-ifdef ENABLE_GROOVIE2
-DEFINES += -DENABLE_GROOVIE2
-endif
-endif
-
-ifdef ENABLE_HOPKINS
-DEFINES += -DENABLE_HOPKINS=$(ENABLE_HOPKINS)
-MODULES += engines/hopkins
-endif
-
-ifdef ENABLE_HUGO
-DEFINES += -DENABLE_HUGO=$(ENABLE_HUGO)
-MODULES += engines/hugo
-endif
-
-ifdef ENABLE_KYRA
-DEFINES += -DENABLE_KYRA=$(ENABLE_KYRA)
-MODULES += engines/kyra
-
-ifdef ENABLE_LOL
-DEFINES += -DENABLE_LOL
-endif
-
-ifdef ENABLE_EOB
-DEFINES += -DENABLE_EOB
-endif
-endif
-
-ifdef ENABLE_LASTEXPRESS
-DEFINES += -DENABLE_LASTEXPRESS=$(ENABLE_LASTEXPRESS)
-MODULES += engines/lastexpress
-endif
-
-ifdef ENABLE_LURE
-DEFINES += -DENABLE_LURE=$(ENABLE_LURE)
-MODULES += engines/lure
-endif
-
-ifdef ENABLE_MADE
-DEFINES += -DENABLE_MADE=$(ENABLE_MADE)
-MODULES += engines/made
-endif
-
-ifdef ENABLE_MOHAWK
-DEFINES += -DENABLE_MOHAWK=$(ENABLE_MOHAWK)
-MODULES += engines/mohawk
-
-ifdef ENABLE_CSTIME
-DEFINES += -DENABLE_CSTIME
-endif
-
-ifdef ENABLE_MYST
-DEFINES += -DENABLE_MYST
-endif
-
-ifdef ENABLE_RIVEN
-DEFINES += -DENABLE_RIVEN
-endif
-endif
-
-ifdef ENABLE_MORTEVIELLE
-DEFINES += -DENABLE_MORTEVIELLE=$(ENABLE_MORTEVIELLE)
-MODULES += engines/mortevielle
-endif
-
-ifdef ENABLE_NEVERHOOD
-DEFINES += -DENABLE_NEVERHOOD=$(ENABLE_NEVERHOOD)
-MODULES += engines/neverhood
-endif
-
-ifdef ENABLE_PARALLACTION
-DEFINES += -DENABLE_PARALLACTION=$(ENABLE_PARALLACTION)
-MODULES += engines/parallaction
-endif
-
-ifdef ENABLE_PEGASUS
-DEFINES += -DENABLE_PEGASUS=$(ENABLE_PEGASUS)
-MODULES += engines/pegasus
-endif
-
-ifdef ENABLE_QUEEN
-DEFINES += -DENABLE_QUEEN=$(ENABLE_QUEEN)
-MODULES += engines/queen
-endif
-
-ifdef ENABLE_SAGA
-DEFINES += -DENABLE_SAGA=$(ENABLE_SAGA)
-MODULES += engines/saga
-
-ifdef ENABLE_IHNM
-DEFINES += -DENABLE_IHNM
-endif
-
-ifdef ENABLE_SAGA2
-DEFINES += -DENABLE_SAGA2
-endif
-endif
-
-ifdef ENABLE_SCI
-DEFINES += -DENABLE_SCI=$(ENABLE_SCI)
-MODULES += engines/sci
-
-ifdef ENABLE_SCI32
-DEFINES += -DENABLE_SCI32
-endif
-endif
-
-ifdef ENABLE_SKY
-DEFINES += -DENABLE_SKY=$(ENABLE_SKY)
-MODULES += engines/sky
-endif
-
-ifdef ENABLE_SWORD1
-DEFINES += -DENABLE_SWORD1=$(ENABLE_SWORD1)
-MODULES += engines/sword1
-endif
-
-ifdef ENABLE_SWORD2
-DEFINES += -DENABLE_SWORD2=$(ENABLE_SWORD2)
-MODULES += engines/sword2
-endif
-
-ifdef ENABLE_SWORD25
-DEFINES += -DENABLE_SWORD25=$(ENABLE_SWORD25)
-MODULES += engines/sword25
-endif
-
-ifdef ENABLE_TESTBED
-DEFINES += -DENABLE_TESTBED=$(ENABLE_TESTBED)
-MODULES += engines/testbed
-endif
-
-ifdef ENABLE_TEENAGENT
-DEFINES += -DENABLE_TEENAGENT=$(ENABLE_TEENAGENT)
-MODULES += engines/teenagent
-endif
-
-ifdef ENABLE_TINSEL
-DEFINES += -DENABLE_TINSEL=$(ENABLE_TINSEL)
-MODULES += engines/tinsel
-endif
-
-ifdef ENABLE_TOLTECS
-DEFINES += -DENABLE_TOLTECS=$(ENABLE_TOLTECS)
-MODULES += engines/toltecs
-endif
-
-ifdef ENABLE_TONY
-DEFINES += -DENABLE_TONY=$(ENABLE_TONY)
-MODULES += engines/tony
-endif
-
-ifdef ENABLE_TOON
-DEFINES += -DENABLE_TOON=$(ENABLE_TOON)
-MODULES += engines/toon
-endif
-
-ifdef ENABLE_TOUCHE
-DEFINES += -DENABLE_TOUCHE=$(ENABLE_TOUCHE)
-MODULES += engines/touche
-endif
-
-ifdef ENABLE_TSAGE
-DEFINES += -DENABLE_TSAGE=$(ENABLE_TSAGE)
-MODULES += engines/tsage
-endif
-
-ifdef ENABLE_TUCKER
-DEFINES += -DENABLE_TUCKER=$(ENABLE_TUCKER)
-MODULES += engines/tucker
-endif
-
-ifdef ENABLE_WINTERMUTE
-DEFINES += -DENABLE_WINTERMUTE=$(ENABLE_WINTERMUTE)
-MODULES += engines/wintermute
-endif
-
-ifdef ENABLE_ZVISION
-DEFINES += -DENABLE_ZVISION=$(ENABLE_ZVISION)
-MODULES += engines/zvision
-endif
diff --git a/engines/fullpipe/configure.engine b/engines/fullpipe/configure.engine
new file mode 100644
index 0000000000..fce5951e26
--- /dev/null
+++ b/engines/fullpipe/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine fullpipe "Full Pipe" no
diff --git a/engines/gob/configure.engine b/engines/gob/configure.engine
new file mode 100644
index 0000000000..8e012f5815
--- /dev/null
+++ b/engines/gob/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine gob "Gobli*ns" yes
diff --git a/engines/groovie/configure.engine b/engines/groovie/configure.engine
new file mode 100644
index 0000000000..84e95a70df
--- /dev/null
+++ b/engines/groovie/configure.engine
@@ -0,0 +1,4 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine groovie "Groovie" yes "groovie2" "7th Guest"
+add_engine groovie2 "Groovie 2 games" no "" "" "jpeg"
diff --git a/engines/groovie/font.cpp b/engines/groovie/font.cpp
index d29c22dd02..a55d8fad95 100644
--- a/engines/groovie/font.cpp
+++ b/engines/groovie/font.cpp
@@ -112,7 +112,7 @@ bool T7GFont::load(Common::SeekableReadStream &stream) {
return true;
}
-void T7GFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const {
+void T7GFont::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const {
// We ignore the color, as the font is already colored
const Glyph *glyph = getGlyph(chr);
const byte *src = glyph->pixels;
@@ -125,7 +125,7 @@ void T7GFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 co
}
}
-const T7GFont::Glyph *T7GFont::getGlyph(byte chr) const {
+const T7GFont::Glyph *T7GFont::getGlyph(uint32 chr) const {
assert (chr < 128);
byte numGlyph = _mapChar2Glyph[chr];
diff --git a/engines/groovie/font.h b/engines/groovie/font.h
index 20aaa4cf23..49cf4b7b06 100644
--- a/engines/groovie/font.h
+++ b/engines/groovie/font.h
@@ -37,8 +37,8 @@ public:
int getFontHeight() const { return _maxHeight; }
int getMaxCharWidth() const { return _maxWidth; }
- int getCharWidth(byte chr) const { return getGlyph(chr)->width; }
- void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const;
+ int getCharWidth(uint32 chr) const { return getGlyph(chr)->width; }
+ void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const;
private:
int _maxHeight, _maxWidth;
@@ -55,7 +55,7 @@ private:
byte _mapChar2Glyph[128];
Glyph *_glyphs;
- const Glyph *getGlyph(byte chr) const;
+ const Glyph *getGlyph(uint32 chr) const;
};
} // End of Groovie namespace
diff --git a/engines/hopkins/configure.engine b/engines/hopkins/configure.engine
new file mode 100644
index 0000000000..c38ecd4cd2
--- /dev/null
+++ b/engines/hopkins/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine hopkins "Hopkins FBI" yes "" "" "16bit"
diff --git a/engines/hugo/configure.engine b/engines/hugo/configure.engine
new file mode 100644
index 0000000000..9ab5c54e1e
--- /dev/null
+++ b/engines/hugo/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine hugo "Hugo Trilogy" yes
diff --git a/engines/kyra/configure.engine b/engines/kyra/configure.engine
new file mode 100644
index 0000000000..b7d6334fcc
--- /dev/null
+++ b/engines/kyra/configure.engine
@@ -0,0 +1,5 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine kyra "Kyra" yes "lol eob" "Legend of Kyrandia 1-3"
+add_engine lol "Lands of Lore" yes
+add_engine eob "Eye of the Beholder" yes
diff --git a/engines/lastexpress/configure.engine b/engines/lastexpress/configure.engine
new file mode 100644
index 0000000000..807b1a088b
--- /dev/null
+++ b/engines/lastexpress/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine lastexpress "The Last Express" no "" "" "16bit"
diff --git a/engines/lure/configure.engine b/engines/lure/configure.engine
new file mode 100644
index 0000000000..e9f92893e3
--- /dev/null
+++ b/engines/lure/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine lure "Lure of the Temptress" yes
diff --git a/engines/made/configure.engine b/engines/made/configure.engine
new file mode 100644
index 0000000000..2266712338
--- /dev/null
+++ b/engines/made/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine made "MADE" yes
diff --git a/engines/mohawk/configure.engine b/engines/mohawk/configure.engine
new file mode 100644
index 0000000000..fa9d15cffc
--- /dev/null
+++ b/engines/mohawk/configure.engine
@@ -0,0 +1,6 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine mohawk "Mohawk" yes "cstime myst riven" "Living Books"
+add_engine cstime "Where in Time is Carmen Sandiego?" no
+add_engine riven "Riven: The Sequel to Myst" no "" "" "16bit"
+add_engine myst "Myst" no "" "" "16bit"
diff --git a/engines/mortevielle/configure.engine b/engines/mortevielle/configure.engine
new file mode 100644
index 0000000000..14d6479e7a
--- /dev/null
+++ b/engines/mortevielle/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine mortevielle "Mortevielle" no
diff --git a/engines/neverhood/configure.engine b/engines/neverhood/configure.engine
new file mode 100644
index 0000000000..0767a631f9
--- /dev/null
+++ b/engines/neverhood/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine neverhood "Neverhood" no
diff --git a/engines/parallaction/configure.engine b/engines/parallaction/configure.engine
new file mode 100644
index 0000000000..babca4579f
--- /dev/null
+++ b/engines/parallaction/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine parallaction "Parallaction" yes
diff --git a/engines/pegasus/configure.engine b/engines/pegasus/configure.engine
new file mode 100644
index 0000000000..ed7e295287
--- /dev/null
+++ b/engines/pegasus/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine pegasus "The Journeyman Project: Pegasus Prime" yes "" "" "16bit"
diff --git a/engines/plugins_table.h b/engines/plugins_table.h
deleted file mode 100644
index 38cd43ac74..0000000000
--- a/engines/plugins_table.h
+++ /dev/null
@@ -1,130 +0,0 @@
-// This file is being included by "base/plugins.cpp"
-#if PLUGIN_ENABLED_STATIC(SCUMM)
-LINK_PLUGIN(SCUMM)
-#endif
-#if PLUGIN_ENABLED_STATIC(AGI)
-LINK_PLUGIN(AGI)
-#endif
-#if PLUGIN_ENABLED_STATIC(AGOS)
-LINK_PLUGIN(AGOS)
-#endif
-#if PLUGIN_ENABLED_STATIC(AVALANCHE)
-LINK_PLUGIN(AVALANCHE)
-#endif
-#if PLUGIN_ENABLED_STATIC(CGE)
-LINK_PLUGIN(CGE)
-#endif
-#if PLUGIN_ENABLED_STATIC(CINE)
-LINK_PLUGIN(CINE)
-#endif
-#if PLUGIN_ENABLED_STATIC(COMPOSER)
-LINK_PLUGIN(COMPOSER)
-#endif
-#if PLUGIN_ENABLED_STATIC(CRUISE)
-LINK_PLUGIN(CRUISE)
-#endif
-#if PLUGIN_ENABLED_STATIC(DRACI)
-LINK_PLUGIN(DRACI)
-#endif
-#if PLUGIN_ENABLED_STATIC(DRASCULA)
-LINK_PLUGIN(DRASCULA)
-#endif
-#if PLUGIN_ENABLED_STATIC(DREAMWEB)
-LINK_PLUGIN(DREAMWEB)
-#endif
-#if PLUGIN_ENABLED_STATIC(FULLPIPE)
-LINK_PLUGIN(FULLPIPE)
-#endif
-#if PLUGIN_ENABLED_STATIC(GOB)
-LINK_PLUGIN(GOB)
-#endif
-#if PLUGIN_ENABLED_STATIC(GROOVIE)
-LINK_PLUGIN(GROOVIE)
-#endif
-#if PLUGIN_ENABLED_STATIC(HOPKINS)
-LINK_PLUGIN(HOPKINS)
-#endif
-#if PLUGIN_ENABLED_STATIC(HUGO)
-LINK_PLUGIN(HUGO)
-#endif
-#if PLUGIN_ENABLED_STATIC(KYRA)
-LINK_PLUGIN(KYRA)
-#endif
-#if PLUGIN_ENABLED_STATIC(MORTEVIELLE)
-LINK_PLUGIN(MORTEVIELLE)
-#endif
-#if PLUGIN_ENABLED_STATIC(LASTEXPRESS)
-LINK_PLUGIN(LASTEXPRESS)
-#endif
-#if PLUGIN_ENABLED_STATIC(LURE)
-LINK_PLUGIN(LURE)
-#endif
-#if PLUGIN_ENABLED_STATIC(MADE)
-LINK_PLUGIN(MADE)
-#endif
-#if PLUGIN_ENABLED_STATIC(MOHAWK)
-LINK_PLUGIN(MOHAWK)
-#endif
-#if PLUGIN_ENABLED_STATIC(NEVERHOOD)
-LINK_PLUGIN(NEVERHOOD)
-#endif
-#if PLUGIN_ENABLED_STATIC(PARALLACTION)
-LINK_PLUGIN(PARALLACTION)
-#endif
-#if PLUGIN_ENABLED_STATIC(PEGASUS)
-LINK_PLUGIN(PEGASUS)
-#endif
-#if PLUGIN_ENABLED_STATIC(QUEEN)
-LINK_PLUGIN(QUEEN)
-#endif
-#if PLUGIN_ENABLED_STATIC(SAGA)
-LINK_PLUGIN(SAGA)
-#endif
-#if PLUGIN_ENABLED_STATIC(SCI)
-LINK_PLUGIN(SCI)
-#endif
-#if PLUGIN_ENABLED_STATIC(SKY)
-LINK_PLUGIN(SKY)
-#endif
-#if PLUGIN_ENABLED_STATIC(SWORD1)
-LINK_PLUGIN(SWORD1)
-#endif
-#if PLUGIN_ENABLED_STATIC(SWORD2)
-LINK_PLUGIN(SWORD2)
-#endif
-#if PLUGIN_ENABLED_STATIC(SWORD25)
-LINK_PLUGIN(SWORD25)
-#endif
-#if PLUGIN_ENABLED_STATIC(TEENAGENT)
-LINK_PLUGIN(TEENAGENT)
-#endif
-#if PLUGIN_ENABLED_STATIC(TESTBED)
-LINK_PLUGIN(TESTBED)
-#endif
-#if PLUGIN_ENABLED_STATIC(TINSEL)
-LINK_PLUGIN(TINSEL)
-#endif
-#if PLUGIN_ENABLED_STATIC(TOLTECS)
-LINK_PLUGIN(TOLTECS)
-#endif
-#if PLUGIN_ENABLED_STATIC(TONY)
-LINK_PLUGIN(TONY)
-#endif
-#if PLUGIN_ENABLED_STATIC(TOON)
-LINK_PLUGIN(TOON)
-#endif
-#if PLUGIN_ENABLED_STATIC(TSAGE)
-LINK_PLUGIN(TSAGE)
-#endif
-#if PLUGIN_ENABLED_STATIC(TOUCHE)
-LINK_PLUGIN(TOUCHE)
-#endif
-#if PLUGIN_ENABLED_STATIC(TUCKER)
-LINK_PLUGIN(TUCKER)
-#endif
-#if PLUGIN_ENABLED_STATIC(WINTERMUTE)
-LINK_PLUGIN(WINTERMUTE)
-#endif
-#if PLUGIN_ENABLED_STATIC(ZVISION)
-LINK_PLUGIN(ZVISION)
-#endif
diff --git a/engines/queen/configure.engine b/engines/queen/configure.engine
new file mode 100644
index 0000000000..c8766743f9
--- /dev/null
+++ b/engines/queen/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine queen "Flight of the Amazon Queen" yes
diff --git a/engines/saga/configure.engine b/engines/saga/configure.engine
new file mode 100644
index 0000000000..99e2ab367b
--- /dev/null
+++ b/engines/saga/configure.engine
@@ -0,0 +1,5 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine saga "SAGA" yes "ihnm saga2" "ITE"
+add_engine ihnm "IHNM" yes
+add_engine saga2 "SAGA 2 games" no
diff --git a/engines/sci/configure.engine b/engines/sci/configure.engine
new file mode 100644
index 0000000000..d1c45a4654
--- /dev/null
+++ b/engines/sci/configure.engine
@@ -0,0 +1,4 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine sci "SCI" yes "sci32" "SCI 0-1.1 games"
+add_engine sci32 "SCI32 games" no
diff --git a/engines/scumm/configure.engine b/engines/scumm/configure.engine
new file mode 100644
index 0000000000..e1de788061
--- /dev/null
+++ b/engines/scumm/configure.engine
@@ -0,0 +1,5 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine scumm "SCUMM" yes "scumm_7_8 he" "v0-v6 games"
+add_engine scumm_7_8 "v7 & v8 games" yes
+add_engine he "HE71+ games" yes
diff --git a/engines/sky/configure.engine b/engines/sky/configure.engine
new file mode 100644
index 0000000000..32b84849cb
--- /dev/null
+++ b/engines/sky/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine sky "Beneath a Steel Sky" yes
diff --git a/engines/sword1/configure.engine b/engines/sword1/configure.engine
new file mode 100644
index 0000000000..0578d176a9
--- /dev/null
+++ b/engines/sword1/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine sword1 "Broken Sword" yes
diff --git a/engines/sword2/configure.engine b/engines/sword2/configure.engine
new file mode 100644
index 0000000000..7153605433
--- /dev/null
+++ b/engines/sword2/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine sword2 "Broken Sword II" yes
diff --git a/engines/sword25/configure.engine b/engines/sword25/configure.engine
new file mode 100644
index 0000000000..1729bbeb33
--- /dev/null
+++ b/engines/sword25/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine sword25 "Broken Sword 2.5" no "" "" "png zlib 16bit"
diff --git a/engines/teenagent/configure.engine b/engines/teenagent/configure.engine
new file mode 100644
index 0000000000..223a0e884c
--- /dev/null
+++ b/engines/teenagent/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine teenagent "Teen Agent" yes
diff --git a/engines/testbed/configure.engine b/engines/testbed/configure.engine
new file mode 100644
index 0000000000..c0a68c8eb8
--- /dev/null
+++ b/engines/testbed/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine testbed "TestBed: the Testing framework" no
diff --git a/engines/tinsel/configure.engine b/engines/tinsel/configure.engine
new file mode 100644
index 0000000000..c0f3e0a18d
--- /dev/null
+++ b/engines/tinsel/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine tinsel "Tinsel" yes
diff --git a/engines/toltecs/configure.engine b/engines/toltecs/configure.engine
new file mode 100644
index 0000000000..be5533efa2
--- /dev/null
+++ b/engines/toltecs/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine toltecs "3 Skulls of the Toltecs" yes
diff --git a/engines/tony/configure.engine b/engines/tony/configure.engine
new file mode 100644
index 0000000000..f85f45d158
--- /dev/null
+++ b/engines/tony/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine tony "Tony Tough and the Night of Roasted Moths" yes "" "" "16bit"
diff --git a/engines/toon/configure.engine b/engines/toon/configure.engine
new file mode 100644
index 0000000000..00c98f7d8a
--- /dev/null
+++ b/engines/toon/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine toon "Toonstruck" yes
diff --git a/engines/touche/configure.engine b/engines/touche/configure.engine
new file mode 100644
index 0000000000..777578e623
--- /dev/null
+++ b/engines/touche/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine touche "Touche: The Adventures of the Fifth Musketeer" yes
diff --git a/engines/tsage/configure.engine b/engines/tsage/configure.engine
new file mode 100644
index 0000000000..2b8edf8266
--- /dev/null
+++ b/engines/tsage/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine tsage "TsAGE" yes
diff --git a/engines/tucker/configure.engine b/engines/tucker/configure.engine
new file mode 100644
index 0000000000..06676cf0a4
--- /dev/null
+++ b/engines/tucker/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine tucker "Bud Tucker in Double Trouble" yes
diff --git a/engines/wintermute/base/font/base_font_truetype.cpp b/engines/wintermute/base/font/base_font_truetype.cpp
index d6f09141c9..b879e789e3 100644
--- a/engines/wintermute/base/font/base_font_truetype.cpp
+++ b/engines/wintermute/base/font/base_font_truetype.cpp
@@ -121,7 +121,7 @@ int BaseFontTT::getTextWidth(const byte *text, int maxLength) {
}
if (maxLength >= 0 && textStr.size() > (uint32)maxLength) {
- textStr = Common::String(textStr.c_str(), (uint32)maxLength);
+ textStr = WideString(textStr.c_str(), (uint32)maxLength);
}
//text = text.substr(0, MaxLength); // TODO: Remove
@@ -155,19 +155,19 @@ void BaseFontTT::drawText(const byte *text, int x, int y, int width, TTextAlign
return;
}
- WideString textStr = (const char *)text;
+ WideString textStr;
// TODO: Why do we still insist on Widestrings everywhere?
- /* if (_gameRef->_textEncoding == TEXT_UTF8) text = StringUtil::Utf8ToWide((char *)Text);
- else text = StringUtil::AnsiToWide((char *)Text);*/
// HACK: J.U.L.I.A. uses CP1252, we need to fix that,
// And we still don't have any UTF8-support.
- if (_gameRef->_textEncoding != TEXT_UTF8) {
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ textStr = StringUtil::utf8ToWide((const char *)text);
+ } else {
textStr = StringUtil::ansiToWide((const char *)text);
}
if (maxLength >= 0 && textStr.size() > (uint32)maxLength) {
- textStr = Common::String(textStr.c_str(), (uint32)maxLength);
+ textStr = WideString(textStr.c_str(), (uint32)maxLength);
}
//text = text.substr(0, MaxLength); // TODO: Remove
@@ -248,7 +248,7 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
//TextLineList lines;
// TODO: Use WideString-conversion here.
//WrapText(text, width, maxHeight, lines);
- Common::Array<Common::String> lines;
+ Common::Array<WideString> lines;
_font->wordWrapText(text, width, lines);
while (maxHeight > 0 && lines.size() * _lineHeight > maxHeight) {
@@ -267,7 +267,8 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
alignment = Graphics::kTextAlignRight;
}
- debugC(kWintermuteDebugFont, "%s %d %d %d %d", text.c_str(), RGBCOLGetR(_layers[0]->_color), RGBCOLGetG(_layers[0]->_color), RGBCOLGetB(_layers[0]->_color), RGBCOLGetA(_layers[0]->_color));
+ // TODO: This debug call does not work with WideString because text.c_str() returns an uint32 array.
+ //debugC(kWintermuteDebugFont, "%s %d %d %d %d", text.c_str(), RGBCOLGetR(_layers[0]->_color), RGBCOLGetG(_layers[0]->_color), RGBCOLGetB(_layers[0]->_color), RGBCOLGetA(_layers[0]->_color));
// void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
Graphics::Surface *surface = new Graphics::Surface();
if (_deletableFont) { // We actually have a TTF
@@ -276,7 +277,7 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
}
uint32 useColor = 0xffffffff;
- Common::Array<Common::String>::iterator it;
+ Common::Array<WideString>::iterator it;
int heightOffset = 0;
for (it = lines.begin(); it != lines.end(); ++it) {
_font->drawString(surface, *it, 0, heightOffset, width, useColor, alignment);
@@ -647,9 +648,9 @@ void BaseFontTT::measureText(const WideString &text, int maxWidth, int maxHeight
//TextLineList lines;
if (maxWidth >= 0) {
- Common::Array<Common::String> lines;
+ Common::Array<WideString> lines;
_font->wordWrapText(text, maxWidth, lines);
- Common::Array<Common::String>::iterator it;
+ Common::Array<WideString>::iterator it;
textWidth = 0;
for (it = lines.begin(); it != lines.end(); ++it) {
textWidth = MAX(textWidth, _font->getStringWidth(*it));
diff --git a/engines/wintermute/base/font/base_font_truetype.h b/engines/wintermute/base/font/base_font_truetype.h
index 7a96cdf1b7..edb41a155f 100644
--- a/engines/wintermute/base/font/base_font_truetype.h
+++ b/engines/wintermute/base/font/base_font_truetype.h
@@ -56,9 +56,8 @@ private:
bool _marked;
uint32 _lastUsed;
- BaseCachedTTFontText() {
+ BaseCachedTTFontText() : _text() {
//_text = L"";
- _text = "";
_width = _maxHeight = _maxLength = -1;
_align = TAL_LEFT;
_surface = nullptr;
diff --git a/engines/wintermute/base/scriptables/script_ext_string.cpp b/engines/wintermute/base/scriptables/script_ext_string.cpp
index b6d284442d..65bec03bc1 100644
--- a/engines/wintermute/base/scriptables/script_ext_string.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_string.cpp
@@ -298,21 +298,13 @@ bool SXString::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
uint32 start = 0;
for(uint32 i = 0; i < str.size() + 1; i++) {
- char ch = str.c_str()[i];
- if(ch=='\0' || delims.contains(ch))
- {
- char *part = new char[i - start + 1];
- if(i != start) {
- Common::strlcpy(part, str.c_str() + start, i - start + 1);
- part[i - start] = '\0';
+ uint32 ch = str[i];
+ if (ch =='\0' || delims.contains(ch)) {
+ if (i != start) {
+ parts.push_back(WideString(str.c_str() + start, i - start + 1));
} else {
- part[0] = '\0';
+ parts.push_back(WideString());
}
- val = new ScValue(_gameRef, part);
- array->push(val);
- delete[] part;
- delete val;
- val = nullptr;
start = i + 1;
}
}
diff --git a/engines/wintermute/configure.engine b/engines/wintermute/configure.engine
new file mode 100644
index 0000000000..673549b46b
--- /dev/null
+++ b/engines/wintermute/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine wintermute "Wintermute" no "" "" "jpeg png zlib vorbis 16bit"
diff --git a/engines/wintermute/dctypes.h b/engines/wintermute/dctypes.h
index b40322147f..4371ee4889 100644
--- a/engines/wintermute/dctypes.h
+++ b/engines/wintermute/dctypes.h
@@ -31,6 +31,7 @@
#include "common/str.h"
+#include "common/ustr.h"
#include "common/list.h"
#include "common/array.h"
@@ -41,7 +42,7 @@ namespace Wintermute {
//typedef std::wstring WideString;
typedef Common::String AnsiString;
typedef Common::String Utf8String;
-typedef Common::String WideString; // NB: Not actually true I presume.
+typedef Common::U32String WideString;
typedef Common::List<WideString> WideStringList;
typedef Common::List<AnsiString> AnsiStringList;
diff --git a/engines/wintermute/utils/string_util.cpp b/engines/wintermute/utils/string_util.cpp
index d5d6c7f702..702dd04c27 100644
--- a/engines/wintermute/utils/string_util.cpp
+++ b/engines/wintermute/utils/string_util.cpp
@@ -48,201 +48,96 @@ bool StringUtil::compareNoCase(const AnsiString &str1, const AnsiString &str2) {
return (str1lc == str2lc);
}*/
-Common::String StringUtil::substituteUtf8Characters(Common::String &str) {
- uint strSize = str.size();
- Common::String punctuation("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~");
-
- if (isAscii(str))
- return str;
-
- for (uint32 i = 0; i < strSize; i++) {
- if (!Common::isAlnum(str[i]) && str[i] != ' ' && !punctuation.contains(str[i])) {
- // Replace some UTF-8 characters with (almost) equivalent ANSII ones
- if ((byte)str[i] == 0xc2 && i + 1 < str.size() && (byte)str[i + 1] == 0xa9) {
- // UTF-8 copyright character, substitute with 'c'
- str.deleteChar(i);
- str.setChar('c', i);
- strSize--;
- }
- }
- }
-
- return str;
-}
-
-bool StringUtil::isAscii(const Common::String &str) {
- Common::String punctuation("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~");
-
- for (uint32 i = 0; i < str.size(); i++) {
- if (!Common::isAlnum(str[i]) && str[i] != ' ' && !punctuation.contains(str[i]))
- return false;
- }
-
- return true;
-}
-
//////////////////////////////////////////////////////////////////////////
WideString StringUtil::utf8ToWide(const Utf8String &Utf8Str) {
- // WORKAROUND: Since wide strings aren't supported yet, we make this function
- // work at least with ASCII strings. This should cover all English versions.
- Common::String asciiString = Utf8Str;
- asciiString = substituteUtf8Characters(asciiString);
- if (isAscii(asciiString)) {
- // No special (UTF-8) characters found, just return the string
- return asciiString;
- } else {
- warning("String contains special (UTF-8) characters: '%s'", Utf8Str.c_str());
- }
-
- error("StringUtil::Utf8ToWide - WideString not supported yet for UTF-8 characters");
-
- /* size_t WideSize = Utf8Str.size();
-
- if (sizeof(wchar_t) == 2) {
- wchar_t *WideStringNative = new wchar_t[WideSize + 1];
-
- const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(Utf8Str.c_str());
- const UTF8 *SourceEnd = SourceStart + WideSize;
+ size_t wideSize = Utf8Str.size();
- UTF16 *TargetStart = reinterpret_cast<UTF16 *>(WideStringNative);
- UTF16 *TargetEnd = TargetStart + WideSize + 1;
+ uint32 *wideStringNative = new uint32[wideSize + 1];
- ConversionResult res = ConvertUTF8toUTF16(&SourceStart, SourceEnd, &TargetStart, TargetEnd, strictConversion);
- if (res != conversionOK) {
- delete[] WideStringNative;
- return L"";
- }
- *TargetStart = 0;
- WideString ResultString(WideStringNative);
- delete[] WideStringNative;
+ const UTF8 *sourceStart = reinterpret_cast<const UTF8 *>(Utf8Str.c_str());
+ const UTF8 *sourceEnd = sourceStart + wideSize;
- return ResultString;
- } else if (sizeof(wchar_t) == 4) {
- wchar_t *WideStringNative = new wchar_t[WideSize + 1];
+ UTF32 *targetStart = reinterpret_cast<UTF32 *>(wideStringNative);
+ UTF32 *targetEnd = targetStart + wideSize;
- const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(Utf8Str.c_str());
- const UTF8 *SourceEnd = SourceStart + WideSize;
-
- UTF32 *TargetStart = reinterpret_cast<UTF32 *>(WideStringNative);
- UTF32 *TargetEnd = TargetStart + WideSize;
-
- ConversionResult res = ConvertUTF8toUTF32(&SourceStart, SourceEnd, &TargetStart, TargetEnd, strictConversion);
- if (res != conversionOK) {
- delete[] WideStringNative;
- return L"";
- }
- *TargetStart = 0;
- WideString ResultString(WideStringNative);
- delete[] WideStringNative;
-
- return ResultString;
- } else {
- return L"";
- }*/
- return "";
+ ConversionResult res = ConvertUTF8toUTF32(&sourceStart, sourceEnd, &targetStart, targetEnd, strictConversion);
+ if (res != conversionOK) {
+ delete[] wideStringNative;
+ return WideString();
+ }
+ *targetStart = 0;
+ WideString resultString(wideStringNative);
+ delete[] wideStringNative;
+ return resultString;
}
//////////////////////////////////////////////////////////////////////////
Utf8String StringUtil::wideToUtf8(const WideString &WideStr) {
- // WORKAROUND: Since UTF-8 strings aren't supported yet, we make this function
- // work at least with ASCII strings. This should cover all English versions.
- Common::String asciiString = WideStr;
- asciiString = substituteUtf8Characters(asciiString);
- if (isAscii(asciiString)) {
- // No special (UTF-8) characters found, just return the string
- return asciiString;
- } else {
- warning("String contains special (UTF-8) characters: '%s'", WideStr.c_str());
- }
+ size_t wideSize = WideStr.size();
- error("StringUtil::wideToUtf8 - WideString not supported yet for UTF-8 characters");
-
- /* size_t WideSize = WideStr.length();
+ size_t utf8Size = 4 * wideSize + 1;
+ char *utf8StringNative = new char[utf8Size];
- if (sizeof(wchar_t) == 2) {
- size_t utf8Size = 3 * WideSize + 1;
- char *utf8StringNative = new char[Utf8Size];
+ const UTF32 *sourceStart = reinterpret_cast<const UTF32 *>(WideStr.c_str());
+ const UTF32 *sourceEnd = sourceStart + wideSize;
- const UTF16 *SourceStart = reinterpret_cast<const UTF16 *>(WideStr.c_str());
- const UTF16 *SourceEnd = SourceStart + WideSize;
+ UTF8 *targetStart = reinterpret_cast<UTF8 *>(utf8StringNative);
+ UTF8 *targetEnd = targetStart + utf8Size;
- UTF8 *TargetStart = reinterpret_cast<UTF8 *>(Utf8StringNative);
- UTF8 *TargetEnd = TargetStart + Utf8Size;
-
- ConversionResult res = ConvertUTF16toUTF8(&SourceStart, SourceEnd, &TargetStart, TargetEnd, strictConversion);
- if (res != conversionOK) {
- delete[] Utf8StringNative;
- return (Utf8String)"";
- }
- *TargetStart = 0;
- Utf8String ResultString(Utf8StringNative);
- delete[] Utf8StringNative;
- return ResultString;
- } else if (sizeof(wchar_t) == 4) {
- size_t utf8Size = 4 * WideSize + 1;
- char *utf8StringNative = new char[Utf8Size];
-
- const UTF32 *SourceStart = reinterpret_cast<const UTF32 *>(WideStr.c_str());
- const UTF32 *SourceEnd = SourceStart + WideSize;
-
- UTF8 *TargetStart = reinterpret_cast<UTF8 *>(Utf8StringNative);
- UTF8 *TargetEnd = TargetStart + Utf8Size;
-
- ConversionResult res = ConvertUTF32toUTF8(&SourceStart, SourceEnd, &TargetStart, TargetEnd, strictConversion);
- if (res != conversionOK) {
- delete[] Utf8StringNative;
- return (Utf8String)"";
- }
- *TargetStart = 0;
- Utf8String ResultString(Utf8StringNative);
- delete[] Utf8StringNative;
- return ResultString;
- } else {
- return (Utf8String)"";
- }*/
- return "";
+ ConversionResult res = ConvertUTF32toUTF8(&sourceStart, sourceEnd, &targetStart, targetEnd, strictConversion);
+ if (res != conversionOK) {
+ delete[] utf8StringNative;
+ return Utf8String();
+ }
+ *targetStart = 0;
+ Utf8String resultString(utf8StringNative);
+ delete[] utf8StringNative;
+ return resultString;
}
//////////////////////////////////////////////////////////////////////////
WideString StringUtil::ansiToWide(const AnsiString &str) {
- // TODO: This function gets called a lot, so warnings like these drown out the usefull information
- Common::String converted = "";
- uint32 index = 0;
- while (index != str.size()) {
- byte c = str[index];
- if (c == 146) {
- converted += (char)39; // Replace right-quote with apostrophe
- } else if (c == 133) {
- converted += Common::String("..."); // Replace ...-symbol with ...
+ WideString result;
+ for (AnsiString::const_iterator i = str.begin(), end = str.end(); i != end; ++i) {
+ const byte c = *i;
+ if (c < 0x80 || c >= 0xA0) {
+ result += c;
} else {
- converted += c;
+ uint32 utf32 = _ansiToUTF32[c - 0x80];
+ if (utf32) {
+ result += utf32;
+ } else {
+ // It's an invalid CP1252 character...
+ }
}
- index++;
}
- // using default os locale!
-
- /* setlocale(LC_CTYPE, "");
- size_t wideSize = mbstowcs(NULL, str.c_str(), 0) + 1;
- wchar_t *wstr = new wchar_t[WideSize];
- mbstowcs(wstr, str.c_str(), WideSize);
- WideString ResultString(wstr);
- delete[] wstr;
- return ResultString;*/
- return WideString(converted);
+ return result;
}
//////////////////////////////////////////////////////////////////////////
AnsiString StringUtil::wideToAnsi(const WideString &wstr) {
- // using default os locale!
- // TODO: This function gets called a lot, so warnings like these drown out the usefull information
- /* setlocale(LC_CTYPE, "");
- size_t wideSize = wcstombs(NULL, wstr.c_str(), 0) + 1;
- char *str = new char[WideSize];
- wcstombs(str, wstr.c_str(), WideSize);
- AnsiString ResultString(str);
- delete[] str;
- return ResultString;*/
- return AnsiString(wstr);
+ AnsiString result;
+ for (WideString::const_iterator i = wstr.begin(), end = wstr.end(); i != end; ++i) {
+ const uint32 c = *i;
+ if (c < 0x80 || (c >= 0xA0 && c <= 0xFF)) {
+ result += c;
+ } else {
+ uint32 ansi = 0xFFFFFFFF;
+ for (uint j = 0; j < ARRAYSIZE(_ansiToUTF32); ++j) {
+ if (_ansiToUTF32[j] == c) {
+ ansi = j + 0x80;
+ break;
+ }
+ }
+
+ if (ansi != 0xFFFFFFFF) {
+ result += ansi;
+ } else {
+ // There's no valid CP1252 code for this character...
+ }
+ }
+ }
+ return result;
}
//////////////////////////////////////////////////////////////////////////
@@ -256,12 +151,7 @@ bool StringUtil::isUtf8BOM(const byte *buffer, uint32 bufferSize) {
//////////////////////////////////////////////////////////////////////////
int StringUtil::indexOf(const WideString &str, const WideString &toFind, size_t startFrom) {
- const char *index = strstr(str.c_str(), toFind.c_str());
- if (index == nullptr) {
- return -1;
- } else {
- return index - str.c_str();
- }
+ return str.find(toFind, startFrom);
}
Common::String StringUtil::encodeSetting(const Common::String &str) {
@@ -282,5 +172,10 @@ AnsiString StringUtil::toString(int val) {
return Common::String::format("%d", val);
}
+// Mapping of CP1252 characters 0x80...0x9F into UTF-32
+uint32 StringUtil::_ansiToUTF32[32] = {
+ 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
+ 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178
+};
} // End of namespace Wintermute
diff --git a/engines/wintermute/utils/string_util.h b/engines/wintermute/utils/string_util.h
index 05931beb79..14c40fcb2b 100644
--- a/engines/wintermute/utils/string_util.h
+++ b/engines/wintermute/utils/string_util.h
@@ -37,8 +37,6 @@ class StringUtil {
public:
static bool compareNoCase(const AnsiString &str1, const AnsiString &str2);
//static bool compareNoCase(const WideString &str1, const WideString &str2);
- static bool isAscii(const Common::String &str);
- static Common::String substituteUtf8Characters(Common::String &str);
static WideString utf8ToWide(const Utf8String &Utf8Str);
static Utf8String wideToUtf8(const WideString &WideStr);
static WideString ansiToWide(const AnsiString &str);
@@ -51,6 +49,9 @@ public:
static Common::String decodeSetting(const Common::String &str);
static AnsiString toString(int val);
+
+private:
+ static uint32 _ansiToUTF32[32];
};
} // End of namespace Wintermute
diff --git a/engines/zvision/configure.engine b/engines/zvision/configure.engine
new file mode 100644
index 0000000000..02e31943af
--- /dev/null
+++ b/engines/zvision/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine zvision "ZVision" no "" "" "freetype2 16bit"
diff --git a/graphics/font.cpp b/graphics/font.cpp
index a852274b06..e9f139c478 100644
--- a/graphics/font.cpp
+++ b/graphics/font.cpp
@@ -26,93 +26,32 @@
namespace Graphics {
-int Font::getKerningOffset(byte left, byte right) const {
+int Font::getKerningOffset(uint32 left, uint32 right) const {
return 0;
}
-int Font::getStringWidth(const Common::String &str) const {
+namespace {
+
+template<class StringType>
+int getStringWidthImpl(const Font &font, const StringType &str) {
int space = 0;
- uint last = 0;
+ typename StringType::unsigned_type last = 0;
for (uint i = 0; i < str.size(); ++i) {
- const uint cur = str[i];
- space += getCharWidth(cur) + getKerningOffset(last, cur);
+ const typename StringType::unsigned_type cur = str[i];
+ space += font.getCharWidth(cur) + font.getKerningOffset(last, cur);
last = cur;
}
return space;
}
-void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) const {
+template<class StringType>
+void drawStringImpl(const Font &font, Surface *dst, const StringType &str, int x, int y, int w, uint32 color, TextAlign align, int deltax) {
assert(dst != 0);
- const int leftX = x, rightX = x + w;
- uint i;
- Common::String s = sOld;
- int width = getStringWidth(s);
- Common::String str;
-
- if (useEllipsis && width > w && s.hasSuffix("...")) {
- // String is too wide. Check whether it ends in an ellipsis
- // ("..."). If so, remove that and try again!
- s.deleteLastChar();
- s.deleteLastChar();
- s.deleteLastChar();
- width = getStringWidth(s);
- }
-
- if (useEllipsis && width > w) {
- // String is too wide. So we shorten it "intelligently" by
- // replacing parts of the string by an ellipsis. There are
- // three possibilities for this: replace the start, the end, or
- // the middle of the string. What is best really depends on the
- // context; but unless we want to make this configurable,
- // replacing the middle seems to be a good compromise.
-
- const int ellipsisWidth = getStringWidth("...");
-
- // SLOW algorithm to remove enough of the middle. But it is good enough
- // for now.
- const int halfWidth = (w - ellipsisWidth) / 2;
- int w2 = 0;
- uint last = 0;
-
- for (i = 0; i < s.size(); ++i) {
- const uint cur = s[i];
- int charWidth = getCharWidth(cur) + getKerningOffset(last, cur);
- if (w2 + charWidth > halfWidth)
- break;
- last = cur;
- w2 += charWidth;
- str += cur;
- }
-
- // At this point we know that the first 'i' chars are together 'w2'
- // pixels wide. We took the first i-1, and add "..." to them.
- str += "...";
- last = '.';
- // The original string is width wide. Of those we already skipped past
- // w2 pixels, which means (width - w2) remain.
- // The new str is (w2+ellipsisWidth) wide, so we can accommodate about
- // (w - (w2+ellipsisWidth)) more pixels.
- // Thus we skip ((width - w2) - (w - (w2+ellipsisWidth))) =
- // (width + ellipsisWidth - w)
- int skip = width + ellipsisWidth - w;
- for (; i < s.size() && skip > 0; ++i) {
- const uint cur = s[i];
- skip -= getCharWidth(cur) + getKerningOffset(last, cur);
- last = cur;
- }
-
- // Append the remaining chars, if any
- for (; i < s.size(); ++i) {
- str += s[i];
- }
-
- width = getStringWidth(str);
- } else {
- str = s;
- }
+ const int leftX = x, rightX = x + w;
+ int width = font.getStringWidth(str);
if (align == kTextAlignCenter)
x = x + (w - width)/2;
@@ -120,29 +59,29 @@ void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, in
x = x + w - width;
x += deltax;
- uint last = 0;
- for (i = 0; i < str.size(); ++i) {
- const uint cur = str[i];
- x += getKerningOffset(last, cur);
+ typename StringType::unsigned_type last = 0;
+ for (typename StringType::const_iterator i = str.begin(), end = str.end(); i != end; ++i) {
+ const typename StringType::unsigned_type cur = *i;
+ x += font.getKerningOffset(last, cur);
last = cur;
- w = getCharWidth(cur);
+ w = font.getCharWidth(cur);
if (x+w > rightX)
break;
if (x+w >= leftX)
- drawChar(dst, str[i], x, y, color);
+ font.drawChar(dst, cur, x, y, color);
x += w;
}
}
-
+template<class StringType>
struct WordWrapper {
- Common::Array<Common::String> &lines;
+ Common::Array<StringType> &lines;
int actualMaxLineWidth;
- WordWrapper(Common::Array<Common::String> &l) : lines(l), actualMaxLineWidth(0) {
+ WordWrapper(Common::Array<StringType> &l) : lines(l), actualMaxLineWidth(0) {
}
- void add(Common::String &line, int &w) {
+ void add(StringType &line, int &w) {
if (actualMaxLineWidth < w)
actualMaxLineWidth = w;
@@ -153,10 +92,11 @@ struct WordWrapper {
}
};
-int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Common::String> &lines) const {
- WordWrapper wrapper(lines);
- Common::String line;
- Common::String tmpStr;
+template<class StringType>
+int wordWrapTextImpl(const Font &font, const StringType &str, int maxWidth, Common::Array<StringType> &lines) {
+ WordWrapper<StringType> wrapper(lines);
+ StringType line;
+ StringType tmpStr;
int lineWidth = 0;
int tmpWidth = 0;
@@ -173,10 +113,10 @@ int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Co
// of a line. If we encounter such a word, we have to wrap it over multiple
// lines.
- uint last = 0;
- for (Common::String::const_iterator x = str.begin(); x != str.end(); ++x) {
- const byte c = *x;
- const int w = getCharWidth(c) + getKerningOffset(last, c);
+ typename StringType::unsigned_type last = 0;
+ for (typename StringType::const_iterator x = str.begin(); x != str.end(); ++x) {
+ const typename StringType::unsigned_type c = *x;
+ const int w = font.getCharWidth(c) + font.getKerningOffset(last, c);
last = c;
const bool wouldExceedWidth = (lineWidth + tmpWidth + w > maxWidth);
@@ -212,7 +152,7 @@ int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Co
tmpStr.deleteChar(0);
// This is not very fast, but it is the simplest way to
// assure we do not mess something up because of kerning.
- tmpWidth = getStringWidth(tmpStr);
+ tmpWidth = font.getStringWidth(tmpStr);
}
} else {
wrapper.add(tmpStr, tmpWidth);
@@ -232,5 +172,98 @@ int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Co
return wrapper.actualMaxLineWidth;
}
+} // End of anonymous namespace
+
+int Font::getStringWidth(const Common::String &str) const {
+ return getStringWidthImpl(*this, str);
+}
+
+int Font::getStringWidth(const Common::U32String &str) const {
+ return getStringWidthImpl(*this, str);
+}
+
+void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) const {
+ Common::String s = sOld;
+ int width = getStringWidth(s);
+ Common::String str;
+
+ if (useEllipsis && width > w && s.hasSuffix("...")) {
+ // String is too wide. Check whether it ends in an ellipsis
+ // ("..."). If so, remove that and try again!
+ s.deleteLastChar();
+ s.deleteLastChar();
+ s.deleteLastChar();
+ width = getStringWidth(s);
+ }
+
+ if (useEllipsis && width > w) {
+ // String is too wide. So we shorten it "intelligently" by
+ // replacing parts of the string by an ellipsis. There are
+ // three possibilities for this: replace the start, the end, or
+ // the middle of the string. What is best really depends on the
+ // context; but unless we want to make this configurable,
+ // replacing the middle seems to be a good compromise.
+
+ const int ellipsisWidth = getStringWidth("...");
+
+ // SLOW algorithm to remove enough of the middle. But it is good enough
+ // for now.
+ const int halfWidth = (w - ellipsisWidth) / 2;
+ int w2 = 0;
+ Common::String::unsigned_type last = 0;
+ uint i;
+
+ for (i = 0; i < s.size(); ++i) {
+ const Common::String::unsigned_type cur = s[i];
+ int charWidth = getCharWidth(cur) + getKerningOffset(last, cur);
+ if (w2 + charWidth > halfWidth)
+ break;
+ last = cur;
+ w2 += charWidth;
+ str += cur;
+ }
+
+ // At this point we know that the first 'i' chars are together 'w2'
+ // pixels wide. We took the first i-1, and add "..." to them.
+ str += "...";
+ last = '.';
+
+ // The original string is width wide. Of those we already skipped past
+ // w2 pixels, which means (width - w2) remain.
+ // The new str is (w2+ellipsisWidth) wide, so we can accommodate about
+ // (w - (w2+ellipsisWidth)) more pixels.
+ // Thus we skip ((width - w2) - (w - (w2+ellipsisWidth))) =
+ // (width + ellipsisWidth - w)
+ int skip = width + ellipsisWidth - w;
+ for (; i < s.size() && skip > 0; ++i) {
+ const Common::String::unsigned_type cur = s[i];
+ skip -= getCharWidth(cur) + getKerningOffset(last, cur);
+ last = cur;
+ }
+
+ // Append the remaining chars, if any
+ for (; i < s.size(); ++i) {
+ str += s[i];
+ }
+
+ width = getStringWidth(str);
+ } else {
+ str = s;
+ }
+
+ drawStringImpl(*this, dst, str, x, y, w, color, align, deltax);
+}
+
+void Font::drawString(Surface *dst, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align) const {
+ drawStringImpl(*this, dst, str, x, y, w, color, align, 0);
+}
+
+int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Common::String> &lines) const {
+ return wordWrapTextImpl(*this, str, maxWidth, lines);
+}
+
+int Font::wordWrapText(const Common::U32String &str, int maxWidth, Common::Array<Common::U32String> &lines) const {
+ return wordWrapTextImpl(*this, str, maxWidth, lines);
+}
} // End of namespace Graphics
diff --git a/graphics/font.h b/graphics/font.h
index 6819b42f52..77b7623a85 100644
--- a/graphics/font.h
+++ b/graphics/font.h
@@ -23,6 +23,7 @@
#define GRAPHICS_FONT_H
#include "common/str.h"
+#include "common/ustr.h"
namespace Common {
template<class T> class Array;
@@ -70,7 +71,7 @@ public:
* @param chr The character to query the width of.
* @return The character's width.
*/
- virtual int getCharWidth(byte chr) const = 0;
+ virtual int getCharWidth(uint32 chr) const = 0;
/**
* Query the kerning offset between two characters.
@@ -79,7 +80,7 @@ public:
* @param right The right character. May be 0.
* @return The horizontal displacement.
*/
- virtual int getKerningOffset(byte left, byte right) const;
+ virtual int getKerningOffset(uint32 left, uint32 right) const;
/**
* Draw a character at a specific point on a surface.
@@ -96,15 +97,17 @@ public:
* @param y The y coordinate where to draw the character.
* @param color The color of the character.
*/
- virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const = 0;
+ virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const = 0;
// TODO: Add doxygen comments to this
void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
+ void drawString(Surface *dst, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft) const;
/**
* Compute and return the width the string str has when rendered using this font.
*/
int getStringWidth(const Common::String &str) const;
+ int getStringWidth(const Common::U32String &str) const;
/**
* Take a text (which may contain newline characters) and word wrap it so that
@@ -120,6 +123,7 @@ public:
* @return the maximal width of any of the lines added to lines
*/
int wordWrapText(const Common::String &str, int maxWidth, Common::Array<Common::String> &lines) const;
+ int wordWrapText(const Common::U32String &str, int maxWidth, Common::Array<Common::U32String> &lines) const;
};
} // End of namespace Graphics
diff --git a/graphics/fonts/bdf.cpp b/graphics/fonts/bdf.cpp
index e523a36ad5..7b2290cc3a 100644
--- a/graphics/fonts/bdf.cpp
+++ b/graphics/fonts/bdf.cpp
@@ -51,7 +51,7 @@ int BdfFont::getMaxCharWidth() const {
return _data.maxAdvance;
}
-int BdfFont::getCharWidth(byte chr) const {
+int BdfFont::getCharWidth(uint32 chr) const {
// In case all font have the same advance value, we use the maximum.
if (!_data.advances)
return _data.maxAdvance;
@@ -85,9 +85,9 @@ void drawCharIntern(byte *ptr, uint pitch, const byte *src, int h, int width, in
}
}
-int BdfFont::mapToIndex(byte ch) const {
+int BdfFont::mapToIndex(uint32 ch) const {
// Check whether the character is included
- if (_data.firstCharacter <= ch && ch <= _data.firstCharacter + _data.numCharacters) {
+ if (_data.firstCharacter <= (int)ch && (int)ch <= _data.firstCharacter + _data.numCharacters) {
if (_data.bitmaps[ch - _data.firstCharacter])
return ch - _data.firstCharacter;
}
@@ -95,7 +95,7 @@ int BdfFont::mapToIndex(byte ch) const {
return _data.defaultCharacter - _data.firstCharacter;
}
-void BdfFont::drawChar(Surface *dst, byte chr, const int tx, const int ty, const uint32 color) const {
+void BdfFont::drawChar(Surface *dst, uint32 chr, const int tx, const int ty, const uint32 color) const {
assert(dst != 0);
// TODO: Where is the relation between the max advance being smaller or
diff --git a/graphics/fonts/bdf.h b/graphics/fonts/bdf.h
index b0166a2095..842e54f851 100644
--- a/graphics/fonts/bdf.h
+++ b/graphics/fonts/bdf.h
@@ -61,14 +61,14 @@ public:
virtual int getFontHeight() const;
virtual int getMaxCharWidth() const;
- virtual int getCharWidth(byte chr) const;
- virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const;
+ virtual int getCharWidth(uint32 chr) const;
+ virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const;
static BdfFont *loadFont(Common::SeekableReadStream &stream);
static bool cacheFontData(const BdfFont &font, const Common::String &filename);
static BdfFont *loadFromCache(Common::SeekableReadStream &stream);
private:
- int mapToIndex(byte ch) const;
+ int mapToIndex(uint32 ch) const;
const BdfFontData _data;
const DisposeAfterUse::Flag _dispose;
diff --git a/graphics/fonts/ttf.cpp b/graphics/fonts/ttf.cpp
index b9e9610d77..be3cd94efa 100644
--- a/graphics/fonts/ttf.cpp
+++ b/graphics/fonts/ttf.cpp
@@ -107,11 +107,11 @@ public:
virtual int getMaxCharWidth() const;
- virtual int getCharWidth(byte chr) const;
+ virtual int getCharWidth(uint32 chr) const;
- virtual int getKerningOffset(byte left, byte right) const;
+ virtual int getKerningOffset(uint32 left, uint32 right) const;
- virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const;
+ virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const;
private:
bool _initialized;
FT_Face _face;
@@ -126,13 +126,14 @@ private:
Surface image;
int xOffset, yOffset;
int advance;
+ FT_UInt slot;
};
- bool cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr);
- typedef Common::HashMap<byte, Glyph> GlyphCache;
- GlyphCache _glyphs;
-
- FT_UInt _glyphSlots[256];
+ bool cacheGlyph(Glyph &glyph, uint32 chr) const;
+ typedef Common::HashMap<uint32, Glyph> GlyphCache;
+ mutable GlyphCache _glyphs;
+ bool _allowLateCaching;
+ void assureCached(uint32 chr) const;
bool _monochrome;
bool _hasKerning;
@@ -140,7 +141,7 @@ private:
TTFFont::TTFFont()
: _initialized(false), _face(), _ttfFile(0), _size(0), _width(0), _height(0), _ascent(0),
- _descent(0), _glyphs(), _glyphSlots(), _monochrome(false), _hasKerning(false) {
+ _descent(0), _glyphs(), _monochrome(false), _hasKerning(false) {
}
TTFFont::~TTFFont() {
@@ -212,19 +213,26 @@ bool TTFFont::load(Common::SeekableReadStream &stream, int size, uint dpi, bool
_height = _ascent - _descent + 1;
if (!mapping) {
+ // Allow loading of all unicode characters.
+ _allowLateCaching = true;
+
// Load all ISO-8859-1 characters.
for (uint i = 0; i < 256; ++i) {
- if (!cacheGlyph(_glyphs[i], _glyphSlots[i], i))
- _glyphSlots[i] = 0;
+ if (!cacheGlyph(_glyphs[i], i)) {
+ _glyphs.erase(i);
+ }
}
} else {
+ // We have a fixed map of characters do not load more later.
+ _allowLateCaching = false;
+
for (uint i = 0; i < 256; ++i) {
const uint32 unicode = mapping[i] & 0x7FFFFFFF;
const bool isRequired = (mapping[i] & 0x80000000) != 0;
// Check whether loading an important glyph fails and error out if
// that is the case.
- if (!cacheGlyph(_glyphs[i], _glyphSlots[i], unicode)) {
- _glyphSlots[i] = 0;
+ if (!cacheGlyph(_glyphs[i], unicode)) {
+ _glyphs.erase(i);
if (isRequired)
return false;
}
@@ -243,7 +251,8 @@ int TTFFont::getMaxCharWidth() const {
return _width;
}
-int TTFFont::getCharWidth(byte chr) const {
+int TTFFont::getCharWidth(uint32 chr) const {
+ assureCached(chr);
GlyphCache::const_iterator glyphEntry = _glyphs.find(chr);
if (glyphEntry == _glyphs.end())
return 0;
@@ -251,12 +260,29 @@ int TTFFont::getCharWidth(byte chr) const {
return glyphEntry->_value.advance;
}
-int TTFFont::getKerningOffset(byte left, byte right) const {
+int TTFFont::getKerningOffset(uint32 left, uint32 right) const {
if (!_hasKerning)
return 0;
- FT_UInt leftGlyph = _glyphSlots[left];
- FT_UInt rightGlyph = _glyphSlots[right];
+ assureCached(left);
+ assureCached(right);
+
+ FT_UInt leftGlyph, rightGlyph;
+ GlyphCache::const_iterator glyphEntry;
+
+ glyphEntry = _glyphs.find(left);
+ if (glyphEntry != _glyphs.end()) {
+ leftGlyph = glyphEntry->_value.slot;
+ } else {
+ return 0;
+ }
+
+ glyphEntry = _glyphs.find(right);
+ if (glyphEntry != _glyphs.end()) {
+ rightGlyph = glyphEntry->_value.slot;
+ } else {
+ return 0;
+ }
if (!leftGlyph || !rightGlyph)
return 0;
@@ -304,7 +330,8 @@ void renderGlyph(uint8 *dstPos, const int dstPitch, const uint8 *srcPos, const i
} // End of anonymous namespace
-void TTFFont::drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const {
+void TTFFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const {
+ assureCached(chr);
GlyphCache::const_iterator glyphEntry = _glyphs.find(chr);
if (glyphEntry == _glyphs.end())
return;
@@ -376,11 +403,13 @@ void TTFFont::drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const
}
}
-bool TTFFont::cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr) {
- slot = FT_Get_Char_Index(_face, chr);
+bool TTFFont::cacheGlyph(Glyph &glyph, uint32 chr) const {
+ FT_UInt slot = FT_Get_Char_Index(_face, chr);
if (!slot)
return false;
+ glyph.slot = slot;
+
// We use the light target and render mode to improve the looks of the
// glyphs. It is most noticable in FreeSansBold.ttf, where otherwise the
// 't' glyph looks like it is cut off on the right side.
@@ -456,12 +485,24 @@ bool TTFFont::cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr) {
default:
warning("TTFFont::cacheGlyph: Unsupported pixel mode %d", bitmap.pixel_mode);
+ glyph.image.free();
return false;
}
return true;
}
+void TTFFont::assureCached(uint32 chr) const {
+ if (!chr || !_allowLateCaching || _glyphs.contains(chr)) {
+ return;
+ }
+
+ Glyph newGlyph;
+ if (cacheGlyph(newGlyph, chr)) {
+ _glyphs[chr] = newGlyph;
+ }
+}
+
Font *loadTTFFont(Common::SeekableReadStream &stream, int size, uint dpi, bool monochrome, const uint32 *mapping) {
TTFFont *font = new TTFFont();
diff --git a/graphics/fonts/winfont.cpp b/graphics/fonts/winfont.cpp
index 3bad92236d..c0ebab19ba 100644
--- a/graphics/fonts/winfont.cpp
+++ b/graphics/fonts/winfont.cpp
@@ -200,7 +200,7 @@ char WinFont::indexToCharacter(uint16 index) const {
return index + _firstChar;
}
-uint16 WinFont::characterToIndex(byte character) const {
+uint16 WinFont::characterToIndex(uint32 character) const {
// Go to the default character if we didn't find a mapping
if (character < _firstChar || character > _lastChar)
character = _defaultChar;
@@ -208,7 +208,7 @@ uint16 WinFont::characterToIndex(byte character) const {
return character - _firstChar;
}
-int WinFont::getCharWidth(byte chr) const {
+int WinFont::getCharWidth(uint32 chr) const {
return _glyphs[characterToIndex(chr)].charWidth;
}
@@ -324,7 +324,7 @@ bool WinFont::loadFromFNT(Common::SeekableReadStream &stream) {
return true;
}
-void WinFont::drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const {
+void WinFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const {
assert(dst);
assert(dst->format.bytesPerPixel == 1 || dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4);
assert(_glyphs);
diff --git a/graphics/fonts/winfont.h b/graphics/fonts/winfont.h
index 4382d7ed6b..2c7ba07b41 100644
--- a/graphics/fonts/winfont.h
+++ b/graphics/fonts/winfont.h
@@ -62,8 +62,8 @@ public:
// Font API
int getFontHeight() const { return _pixHeight; }
int getMaxCharWidth() const { return _maxWidth; }
- int getCharWidth(byte chr) const;
- void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const;
+ int getCharWidth(uint32 chr) const;
+ void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const;
private:
bool loadFromPE(const Common::String &fileName, const WinFontDirEntry &dirEntry);
@@ -72,7 +72,7 @@ private:
uint32 getFontIndex(Common::SeekableReadStream &stream, const WinFontDirEntry &dirEntry);
bool loadFromFNT(Common::SeekableReadStream &stream);
char indexToCharacter(uint16 index) const;
- uint16 characterToIndex(byte character) const;
+ uint16 characterToIndex(uint32 character) const;
uint16 _pixHeight;
uint16 _maxWidth;
diff --git a/ports.mk b/ports.mk
index f9d075707b..9b54b3533b 100644
--- a/ports.mk
+++ b/ports.mk
@@ -318,15 +318,15 @@ else ifeq "$(CUR_BRANCH)" ""
$(error You must be on a release branch)
endif
@echo Creating Code::Blocks project files...
- @cd $(srcdir)/dists/codeblocks && ../../devtools/create_project/create_project ../.. --codeblocks >/dev/null && git add -f *.workspace *.cbp
+ @cd $(srcdir)/dists/codeblocks && ../../devtools/create_project/create_project ../.. --codeblocks >/dev/null && git add -f engines/plugins_table.h *.workspace *.cbp
@echo Creating MSVC8 project files...
- @cd $(srcdir)/dists/msvc8 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 8 >/dev/null && git add -f *.sln *.vcproj *.vsprops
+ @cd $(srcdir)/dists/msvc8 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 8 >/dev/null && git add -f engines/plugins_table.h *.sln *.vcproj *.vsprops
@echo Creating MSVC9 project files...
- @cd $(srcdir)/dists/msvc9 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 9 >/dev/null && git add -f *.sln *.vcproj *.vsprops
+ @cd $(srcdir)/dists/msvc9 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 9 >/dev/null && git add -f engines/plugins_table.h *.sln *.vcproj *.vsprops
@echo Creating MSVC10 project files...
- @cd $(srcdir)/dists/msvc10 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 10 >/dev/null && git add -f *.sln *.vcxproj *.vcxproj.filters *.props
+ @cd $(srcdir)/dists/msvc10 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 10 >/dev/null && git add -f engines/plugins_table.h *.sln *.vcxproj *.vcxproj.filters *.props
@echo Creating MSVC11 project files...
- @cd $(srcdir)/dists/msvc11 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 11 >/dev/null && git add -f *.sln *.vcxproj *.vcxproj.filters *.props
+ @cd $(srcdir)/dists/msvc11 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 11 >/dev/null && git add -f engines/plugins_table.h *.sln *.vcxproj *.vcxproj.filters *.props
@echo
@echo All is done.
@echo Now run