aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/archive.cpp6
-rw-r--r--common/archive.h6
-rw-r--r--common/cosinetables.cpp6
-rw-r--r--common/cosinetables.h9
-rw-r--r--common/rdft.h36
-rw-r--r--common/sinetables.cpp12
-rw-r--r--common/sinetables.h7
-rw-r--r--common/str.cpp19
-rw-r--r--common/str.h5
-rw-r--r--common/winexe.cpp2
-rw-r--r--common/winexe_ne.cpp32
-rw-r--r--common/winexe_ne.h50
12 files changed, 135 insertions, 55 deletions
diff --git a/common/archive.cpp b/common/archive.cpp
index 1323f14805..57ebeb2ca6 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -118,7 +118,7 @@ void SearchSet::addDirectory(const String &name, const FSNode &dir, int priority
add(name, new FSDirectory(dir, depth, flat), priority);
}
-void SearchSet::addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority) {
+void SearchSet::addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority, int depth, bool flat) {
FSList subDirs;
if (!directory.getChildren(subDirs))
return;
@@ -161,9 +161,9 @@ void SearchSet::addSubDirectoriesMatching(const FSNode &directory, String origPa
}
if (nextPattern.empty())
- addDirectory(name, *i, priority);
+ addDirectory(name, *i, priority, depth, flat);
else
- addSubDirectoriesMatching(*i, nextPattern, ignoreCase, priority);
+ addSubDirectoriesMatching(*i, nextPattern, ignoreCase, priority, depth, flat);
}
}
}
diff --git a/common/archive.h b/common/archive.h
index ffd86d786d..2f9736f032 100644
--- a/common/archive.h
+++ b/common/archive.h
@@ -184,8 +184,8 @@ public:
* to assume that this method is using anything other than a simple case insensitive compare.
* Thus do not use any tokens like '*' or '?' in the "caselessName" parameter of this function!
*/
- void addSubDirectoryMatching(const FSNode &directory, const String &caselessName, int priority = 0) {
- addSubDirectoriesMatching(directory, caselessName, true, priority);
+ void addSubDirectoryMatching(const FSNode &directory, const String &caselessName, int priority = 0, int depth = 1, bool flat = false) {
+ addSubDirectoriesMatching(directory, caselessName, true, priority, depth, flat);
}
/**
@@ -208,7 +208,7 @@ public:
*
* @see Common::matchString
*/
- void addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority = 0);
+ void addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority = 0, int depth = 1, bool flat = false);
/**
* Remove an archive from the searchable set.
diff --git a/common/cosinetables.cpp b/common/cosinetables.cpp
index fe8f454e14..3b245750fa 100644
--- a/common/cosinetables.cpp
+++ b/common/cosinetables.cpp
@@ -34,10 +34,10 @@ CosineTable::CosineTable(int bitPrecision) {
int m = 1 << _bitPrecision;
double freq = 2 * M_PI / m;
- _table = new float[m];
+ _table = new float[m / 2];
- // Table contains cos(2*pi*x/n) for 0<=x<=n/4,
- // followed by its reverse
+ // Table contains cos(2*pi*i/m) for 0<=i<m/4,
+ // followed by 3m/4<=i<m
for (int i = 0; i <= m / 4; i++)
_table[i] = cos(i * freq);
diff --git a/common/cosinetables.h b/common/cosinetables.h
index f9fb6fd59a..f5c95ec003 100644
--- a/common/cosinetables.h
+++ b/common/cosinetables.h
@@ -36,7 +36,14 @@ public:
~CosineTable();
/**
- * Get pointer to table
+ * Get pointer to table.
+ *
+ * This table contains 2^bitPrecision/2 entries.
+ * The layout of this table is as follows:
+ * - Entries 0 up to (excluding) 2^bitPrecision/4:
+ * cos(0) till (excluding) cos(1/2*pi)
+ * - Entries 2^bitPrecision/4 up to (excluding) 2^bitPrecision/2:
+ * cos(3/2*pi) till (excluding) cos(2*pi)
*/
const float *getTable() { return _table; }
diff --git a/common/rdft.h b/common/rdft.h
index 3386940404..76e95c363a 100644
--- a/common/rdft.h
+++ b/common/rdft.h
@@ -20,7 +20,7 @@
*
*/
-// Based on eos' (I)RDFT code which is in turn
+// Based on xoreos' (I)RDFT code which is in turn
// Based upon the (I)RDFT code in FFmpeg
// Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot com>
@@ -44,6 +44,40 @@ namespace Common {
*
* Used in engines:
* - scumm
+ *
+ *
+ * It has four modes:
+ *
+ * Below, n = 1 << bits
+ *
+ * (I)DFT_R2C:
+ * input:
+ * n real floats
+ * output:
+ * n/2 complex floats (stored as real part followed by imag part).
+ *
+ * The output represents the first half of the (I)DFT of the input.
+ * If F is the complex (I)DFT of the input, then
+ * output[0] = F[0] + i * F[n/2] and
+ * output[k] = F[k] for k = 1 .. n/2-1.
+ * Note that F[0] and F[k] are real since the input is real, and
+ * the remaining values of F can be reconstructed from symmetry if desired.
+ *
+ * (I)DFT_C2R:
+ * input:
+ * n/2 complex floats
+ * output:
+ * n real floats
+ *
+ * The input encodes a complex vector x of length n that has the
+ * required symmetry to have a real (I)DFT:
+ * x[0] = Re(input[0])
+ * x[k] = input[k] for k = 1 .. n/2-1
+ * x[n/2] = Im(input[0])
+ * x[k] = conj(input[n-k]) for k = n/2+1 .. n-1
+ * The output is then the real (I)DFT of x, divided by 2.
+ *
+ * TODO: Is this division by 2 intentional?
*/
class RDFT {
diff --git a/common/sinetables.cpp b/common/sinetables.cpp
index a6ec99469d..7338166d39 100644
--- a/common/sinetables.cpp
+++ b/common/sinetables.cpp
@@ -34,15 +34,15 @@ SineTable::SineTable(int bitPrecision) {
int m = 1 << _bitPrecision;
double freq = 2 * M_PI / m;
- _table = new float[m];
+ _table = new float[m / 2];
- // Table contains sin(2*pi*x/n) for 0<=x<=n/4,
- // followed by its reverse
- for (int i = 0; i <= m / 4; i++)
+ // Table contains sin(2*pi*i/m) for 0<=i<m/4,
+ // followed by m/2<=i<3m/4
+ for (int i = 0; i < m / 4; i++)
_table[i] = sin(i * freq);
- for (int i = 1; i < m / 4; i++)
- _table[m / 2 - i] = _table[i];
+ for (int i = 0; i < m / 4; i++)
+ _table[m / 4 + i] = -_table[i];
}
SineTable::~SineTable() {
diff --git a/common/sinetables.h b/common/sinetables.h
index 16e203f26d..3489663661 100644
--- a/common/sinetables.h
+++ b/common/sinetables.h
@@ -37,6 +37,13 @@ public:
/**
* Get pointer to table
+ *
+ * This table contains 2^bitPrecision/2 entries.
+ * The layout of this table is as follows:
+ * - Entries 0 up to (excluding) 2^bitPrecision/4:
+ * sin(0) till (excluding) sin(1/2*pi)
+ * - Entries 2^bitPrecision/4 up to (excluding) 2^bitPrecision/2:
+ * sin(pi) till (excluding) sin(3/2*pi)
*/
const float *getTable() { return _table; }
diff --git a/common/str.cpp b/common/str.cpp
index 5d647ee4f0..4a10792373 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -361,6 +361,25 @@ void String::deleteChar(uint32 p) {
_size--;
}
+void String::erase(uint32 p, uint32 len) {
+ assert(p < _size);
+
+ makeUnique();
+ // If len == npos or p + len is over the end, remove all the way to the end
+ if (len == npos || p + len >= _size) {
+ // Delete char at p as well. So _size = (p - 1) + 1
+ _size = p;
+ // Null terminate
+ _str[_size] = 0;
+ return;
+ }
+
+ for ( ; p + len <= _size; p++) {
+ _str[p] = _str[p + len];
+ }
+ _size -= len;
+}
+
void String::clear() {
decRefCount(_extern._refCount);
diff --git a/common/str.h b/common/str.h
index 5039130707..6b4475e1c4 100644
--- a/common/str.h
+++ b/common/str.h
@@ -43,6 +43,8 @@ namespace Common {
* behavior in some operations.
*/
class String {
+public:
+ static const uint32 npos = 0xFFFFFFFF;
protected:
/**
* The size of the internal storage. Increasing this means less heap
@@ -191,6 +193,9 @@ public:
/** Remove the character at position p from the string. */
void deleteChar(uint32 p);
+ /** Remove all characters from position p to the p + len. If len = String::npos, removes all characters to the end */
+ void erase(uint32 p, uint32 len = npos);
+
/** Set character c at position p, replacing the previous character there. */
void setChar(char c, uint32 p);
diff --git a/common/winexe.cpp b/common/winexe.cpp
index 7cfc140452..877ab6baa1 100644
--- a/common/winexe.cpp
+++ b/common/winexe.cpp
@@ -73,7 +73,7 @@ String WinResourceID::toString() const {
if (_idType == kIDTypeString)
return _name;
else if (_idType == kIDTypeNumerical)
- return String::format("%08x", _id);
+ return String::format("0x%08x", _id);
return "";
}
diff --git a/common/winexe_ne.cpp b/common/winexe_ne.cpp
index 8690f6795b..6bb40e0980 100644
--- a/common/winexe_ne.cpp
+++ b/common/winexe_ne.cpp
@@ -187,8 +187,8 @@ uint32 NEResources::getResourceTableOffset() {
static const char *s_resTypeNames[] = {
"", "cursor", "bitmap", "icon", "menu", "dialog", "string",
"font_dir", "font", "accelerator", "rc_data", "msg_table",
- "group_cursor", "group_icon", "version", "dlg_include",
- "plug_play", "vxd", "ani_cursor", "ani_icon", "html",
+ "group_cursor", "group_icon", "", "", "version", "dlg_include",
+ "", "plug_play", "vxd", "ani_cursor", "ani_icon", "html",
"manifest"
};
@@ -200,9 +200,16 @@ bool NEResources::readResourceTable(uint32 offset) {
return false;
uint32 align = 1 << _exe->readUint16LE();
-
uint16 typeID = _exe->readUint16LE();
+
while (typeID != 0) {
+ // High bit of the type means integer type
+ WinResourceID type;
+ if (typeID & 0x8000)
+ type = typeID & 0x7FFF;
+ else
+ type = getResourceString(*_exe, offset + typeID);
+
uint16 resCount = _exe->readUint16LE();
_exe->skip(4); // reserved
@@ -218,17 +225,18 @@ bool NEResources::readResourceTable(uint32 offset) {
res.handle = _exe->readUint16LE();
res.usage = _exe->readUint16LE();
- res.type = typeID;
+ res.type = type;
- if ((id & 0x8000) == 0)
- res.id = getResourceString(*_exe, offset + id);
- else
+ // High bit means integer type
+ if (id & 0x8000)
res.id = id & 0x7FFF;
+ else
+ res.id = getResourceString(*_exe, offset + id);
- if (typeID & 0x8000 && ((typeID & 0x7FFF) < ARRAYSIZE(s_resTypeNames)))
+ if (typeID & 0x8000 && ((typeID & 0x7FFF) < ARRAYSIZE(s_resTypeNames)) && s_resTypeNames[typeID & 0x7FFF][0] != 0)
debug(2, "Found resource %s %s", s_resTypeNames[typeID & 0x7FFF], res.id.toString().c_str());
else
- debug(2, "Found resource %04x %s", typeID, res.id.toString().c_str());
+ debug(2, "Found resource %s %s", type.toString().c_str(), res.id.toString().c_str());
_resources.push_back(res);
}
@@ -257,7 +265,7 @@ String NEResources::getResourceString(SeekableReadStream &exe, uint32 offset) {
return string;
}
-const NEResources::Resource *NEResources::findResource(uint16 type, WinResourceID id) const {
+const NEResources::Resource *NEResources::findResource(const WinResourceID &type, const WinResourceID &id) const {
for (List<Resource>::const_iterator it = _resources.begin(); it != _resources.end(); ++it)
if (it->type == type && it->id == id)
return &*it;
@@ -265,7 +273,7 @@ const NEResources::Resource *NEResources::findResource(uint16 type, WinResourceI
return 0;
}
-SeekableReadStream *NEResources::getResource(uint16 type, WinResourceID id) {
+SeekableReadStream *NEResources::getResource(const WinResourceID &type, const WinResourceID &id) {
const Resource *res = findResource(type, id);
if (!res)
@@ -275,7 +283,7 @@ SeekableReadStream *NEResources::getResource(uint16 type, WinResourceID id) {
return _exe->readStream(res->size);
}
-const Array<WinResourceID> NEResources::getIDList(uint16 type) const {
+const Array<WinResourceID> NEResources::getIDList(const WinResourceID &type) const {
Array<WinResourceID> idArray;
for (List<Resource>::const_iterator it = _resources.begin(); it != _resources.end(); ++it)
diff --git a/common/winexe_ne.h b/common/winexe_ne.h
index 4a1b2343df..f00941412f 100644
--- a/common/winexe_ne.h
+++ b/common/winexe_ne.h
@@ -34,27 +34,27 @@ class SeekableReadStream;
/** The default Windows resources. */
enum NEResourceType {
- kNECursor = 0x8001,
- kNEBitmap = 0x8002,
- kNEIcon = 0x8003,
- kNEMenu = 0x8004,
- kNEDialog = 0x8005,
- kNEString = 0x8006,
- kNEFontDir = 0x8007,
- kNEFont = 0x8008,
- kNEAccelerator = 0x8009,
- kNERCData = 0x800A,
- kNEMessageTable = 0x800B,
- kNEGroupCursor = 0x800C,
- kNEGroupIcon = 0x800D,
- kNEVersion = 0x8010,
- kNEDlgInclude = 0x8011,
- kNEPlugPlay = 0x8013,
- kNEVXD = 0x8014,
- kNEAniCursor = 0x8015,
- kNEAniIcon = 0x8016,
- kNEHTML = 0x8017,
- kNEManifest = 0x8018
+ kNECursor = 0x01,
+ kNEBitmap = 0x02,
+ kNEIcon = 0x03,
+ kNEMenu = 0x04,
+ kNEDialog = 0x05,
+ kNEString = 0x06,
+ kNEFontDir = 0x07,
+ kNEFont = 0x08,
+ kNEAccelerator = 0x09,
+ kNERCData = 0x0A,
+ kNEMessageTable = 0x0B,
+ kNEGroupCursor = 0x0C,
+ kNEGroupIcon = 0x0D,
+ kNEVersion = 0x10,
+ kNEDlgInclude = 0x11,
+ kNEPlugPlay = 0x13,
+ kNEVXD = 0x14,
+ kNEAniCursor = 0x15,
+ kNEAniIcon = 0x16,
+ kNEHTML = 0x17,
+ kNEManifest = 0x18
};
/**
@@ -81,17 +81,17 @@ public:
bool loadFromEXE(SeekableReadStream *stream);
/** Return a list of resources for a given type. */
- const Array<WinResourceID> getIDList(uint16 type) const;
+ const Array<WinResourceID> getIDList(const WinResourceID &type) const;
/** Return a stream to the specified resource (or 0 if non-existent). */
- SeekableReadStream *getResource(uint16 type, WinResourceID id);
+ SeekableReadStream *getResource(const WinResourceID &type, const WinResourceID &id);
private:
/** A resource. */
struct Resource {
WinResourceID id;
- uint16 type; ///< Type of the resource.
+ WinResourceID type; ///< Type of the resource.
uint32 offset; ///< Offset within the EXE.
uint32 size; ///< Size of the data.
@@ -112,7 +112,7 @@ private:
bool readResourceTable(uint32 offset);
/** Find a specific resource. */
- const Resource *findResource(uint16 type, WinResourceID id) const;
+ const Resource *findResource(const WinResourceID &type, const WinResourceID &id) const;
/** Read a resource string. */
static String getResourceString(SeekableReadStream &exe, uint32 offset);