Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
#define SCUMMVM_UTIL 1
#include "../common/str-base.cpp"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,214 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __FILE_H__
#define __FILE_H__
#include <stdio.h>
#include <stdlib.h>
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "common/scummsys.h"
#include "common/endian.h"
#include "common/algorithm.h"
namespace Common {
enum AccessMode {
kFileReadMode = 1,
kFileWriteMode = 2
};
class File {
private:
::FILE *_f;
const byte *_memPtr;
size_t _offset, _size;
public:
File() : _f(nullptr), _memPtr(nullptr), _offset(0), _size(0) {}
bool open(const char *filename, AccessMode mode = kFileReadMode) {
_memPtr = nullptr;
_f = fopen(filename, (mode == kFileReadMode) ? "rb" : "wb+");
return (_f != NULL);
}
bool open(const byte *data, uint size_) {
close();
_f = nullptr;
_memPtr = data;
_size = size_;
return true;
}
void close() {
if (_f)
fclose(_f);
_f = nullptr;
delete[] _memPtr;
_memPtr = nullptr;
}
int seek(int offset, int whence = SEEK_SET) {
if (_f)
return fseek(_f, offset, whence);
switch (whence) {
case SEEK_SET:
_offset = offset;
break;
case SEEK_CUR:
_offset += offset;
break;
case SEEK_END:
_offset = _size + offset;
break;
default:
break;
}
return _offset;
}
void skip(int offset) {
if (_f)
fseek(_f, offset, SEEK_CUR);
else
_offset += offset;
}
long read(void *buffer, size_t len) {
if (_f)
return fread(buffer, 1, len, _f);
uint bytesToRead = CLIP(len, (size_t)0, _size - _offset);
memcpy(buffer, &_memPtr[_offset], bytesToRead);
_offset += bytesToRead;
return bytesToRead;
}
void write(const void *buffer, size_t len) {
assert(_f);
fwrite(buffer, 1, len, _f);
}
void write(File &src, size_t len) {
for (size_t idx = 0; idx < len; ++idx)
writeByte(src.readByte());
}
byte readByte() {
byte v;
read(&v, sizeof(byte));
return v;
}
uint16 readWord() {
uint16 v;
read(&v, sizeof(uint16));
return FROM_LE_16(v);
}
uint readLong() {
uint v;
read(&v, sizeof(uint));
return FROM_LE_32(v);
}
uint readUint16BE() {
uint16 v;
read(&v, sizeof(uint16));
return FROM_BE_16(v);
}
uint readUint16LE() {
uint16 v;
read(&v, sizeof(uint16));
return FROM_LE_16(v);
}
uint readUint32BE() {
uint32 v;
read(&v, sizeof(uint32));
return FROM_BE_32(v);
}
uint readUint32LE() {
uint32 v;
read(&v, sizeof(uint32));
return FROM_LE_32(v);
}
void writeByte(byte v) {
write(&v, sizeof(byte));
}
void writeByte(byte v, int len) {
byte *b = new byte[len];
memset(b, v, len);
write(b, len);
delete[] b;
}
void writeWord(uint16 v) {
uint16 vTemp = TO_LE_16(v);
write(&vTemp, sizeof(uint16));
}
void writeLong(uint v) {
uint vTemp = TO_LE_32(v);
write(&vTemp, sizeof(uint));
}
void writeString(const char *msg) {
if (!msg) {
writeByte(0);
} else {
do {
writeByte(*msg);
} while (*msg++);
}
}
void writeString(File &src) {
char c;
do {
c = src.readByte();
writeByte(c);
} while (c);
}
uint pos() const {
if (_f)
return ftell(_f);
else
return _offset;
}
uint size() const {
if (_f) {
uint currentPos = pos();
fseek(_f, 0, SEEK_END);
uint result = pos();
fseek(_f, currentPos, SEEK_SET);
return result;
} else if (_memPtr) {
return _size;
} else {
return 0;
}
}
bool eof() const {
if (_f)
return feof(_f) != 0;
else if (_memPtr)
return _offset >= _size;
return false;
}
};
}
extern Common::File *inputFile, *outputFile;
#endif

View File

@@ -0,0 +1,85 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COMMON_HASH_STR_H
#define COMMON_HASH_STR_H
#include "hashmap.h"
#include "common/str.h"
namespace Common {
uint hashit(const char *str);
uint hashit_lower(const char *str); // Generate a hash based on the lowercase version of the string
inline uint hashit(const String &str) { return hashit(str.c_str()); }
inline uint hashit_lower(const String &str) { return hashit_lower(str.c_str()); }
// FIXME: The following functors obviously are not consistently named
struct CaseSensitiveString_EqualTo {
bool operator()(const String& x, const String& y) const { return x.equals(y); }
};
struct CaseSensitiveString_Hash {
uint operator()(const String& x) const { return hashit(x.c_str()); }
};
struct IgnoreCase_EqualTo {
bool operator()(const String& x, const String& y) const { return x.equalsIgnoreCase(y); }
};
struct IgnoreCase_Hash {
uint operator()(const String& x) const { return hashit_lower(x.c_str()); }
};
// Specalization of the Hash functor for String objects.
// We do case sensitve hashing here, because that is what
// the default EqualTo is compatible with. If one wants to use
// case insensitve hashing, then only because one wants to use
// IgnoreCase_EqualTo, and then one has to specify a custom
// hash anyway.
template<>
struct Hash<String> {
uint operator()(const String& s) const {
return hashit(s.c_str());
}
};
template<>
struct Hash<const char *> {
uint operator()(const char *s) const {
return hashit(s);
}
};
// String map -- by default case insensitive
typedef HashMap<String, String, IgnoreCase_Hash, IgnoreCase_EqualTo> StringMap;
} // End of namespace Common
#endif

View File

@@ -0,0 +1,108 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// The hash map (associative array) implementation in this file is
// based on the PyDict implementation of CPython. The erase() method
// is based on example code in the Wikipedia article on Hash tables.
#include "common/hashmap.h"
namespace Common {
// Hash function for strings, taken from CPython.
uint hashit(const char *p) {
uint hash = *p << 7;
byte c;
int size = 0;
while ((c = *p++)) {
hash = (1000003 * hash) ^ c;
size++;
}
return hash ^ size;
}
// Like hashit, but converts every char to lowercase before hashing.
uint hashit_lower(const char *p) {
uint hash = tolower(*p) << 7;
byte c;
int size = 0;
while ((c = *p++)) {
hash = (1000003 * hash) ^ tolower(c);
size++;
}
return hash ^ size;
}
#ifdef DEBUG_HASH_COLLISIONS
static double
g_collisions = 0,
g_dummyHits = 0,
g_lookups = 0,
g_collPerLook = 0,
g_capacity = 0,
g_size = 0;
static int g_max_capacity = 0, g_max_size = 0;
static int g_totalHashmaps = 0;
static int g_stats[4] = {0,0,0,0};
void updateHashCollisionStats(int collisions, int dummyHits, int lookups, int arrsize, int nele) {
g_collisions += collisions;
g_lookups += lookups;
g_dummyHits += dummyHits;
if (lookups)
g_collPerLook += (double)collisions / (double)lookups;
g_capacity += arrsize;
g_size += nele;
g_totalHashmaps++;
if (3*nele <= 2*8)
g_stats[0]++;
if (3*nele <= 2*16)
g_stats[1]++;
if (3*nele <= 2*32)
g_stats[2]++;
if (3*nele <= 2*64)
g_stats[3]++;
g_max_capacity = MAX(g_max_capacity, arrsize);
g_max_size = MAX(g_max_size, nele);
debug("%d hashmaps: colls %.1f; dummies hit %.1f, lookups %.1f; ratio %.3f%%; size %f (max: %d); capacity %f (max: %d)",
g_totalHashmaps,
g_collisions / g_totalHashmaps,
g_dummyHits / g_totalHashmaps,
g_lookups / g_totalHashmaps,
100 * g_collPerLook / g_totalHashmaps,
g_size / g_totalHashmaps, g_max_size,
g_capacity / g_totalHashmaps, g_max_capacity);
debug(" %d less than %d; %d less than %d; %d less than %d; %d less than %d",
g_stats[0], 2*8/3,
g_stats[1],2*16/3,
g_stats[2],2*32/3,
g_stats[3],2*64/3);
// TODO:
// * Should record the maximal size of the map during its lifetime, not that at its death
// * Should do some statistics: how many maps are less than 2/3*8, 2/3*16, 2/3*32, ...
}
#endif
} // End of namespace Common

View File

@@ -0,0 +1,626 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// The hash map (associative array) implementation in this file is
// based on the PyDict implementation of CPython.
#ifndef COMMON_HASHMAP_H
#define COMMON_HASHMAP_H
/**
* @def DEBUG_HASH_COLLISIONS
* Enable the following #define if you want to check how many collisions the
* code produces (many collisions indicate either a bad hash function, or a
* hash table that is too small).
*/
//#define DEBUG_HASH_COLLISIONS
/**
* @def USE_HASHMAP_MEMORY_POOL
* Enable the following define to let HashMaps use a memory pool for the
nodes they contain. * This increases memory usage, but also can improve
speed quite a bit.
*/
#define USE_HASHMAP_MEMORY_POOL
#include "common/func.h"
#ifdef DEBUG_HASH_COLLISIONS
#include "common/debug.h"
#endif
#ifdef USE_HASHMAP_MEMORY_POOL
#include "memorypool.h"
#endif
namespace Common {
// The Intel C++ Compiler has difficulties with nested templates.
#if defined(__INTEL_COMPILER)
template<class T> class IteratorImpl;
#endif
/**
* HashMap<Key,Val> maps objects of type Key to objects of type Val.
* For each used Key type, we need an "size_type hashit(Key,size_type)" function
* that computes a hash for the given Key object and returns it as an
* an integer from 0 to hashsize-1, and also an "equality functor".
* that returns true if its two arguments are to be considered
* equal. Also, we assume that "=" works on Val objects for assignment.
*
* If aa is a HashMap<Key,Val>, then space is allocated each time aa[key] is
* referenced, for a new key. If the object is const, then an assertion is
* triggered instead. Hence if you are not sure whether a key is contained in
* the map, use contains() first to check for its presence.
*/
template<class Key, class Val, class HashFunc = Hash<Key>, class EqualFunc = EqualTo<Key> >
class HashMap {
public:
typedef uint size_type;
private:
typedef HashMap<Key, Val, HashFunc, EqualFunc> HM_t;
struct Node {
const Key _key;
Val _value;
explicit Node(const Key &key) : _key(key), _value() {}
Node() : _key(), _value() {}
};
enum {
HASHMAP_PERTURB_SHIFT = 5,
HASHMAP_MIN_CAPACITY = 16,
// The quotient of the next two constants controls how much the
// internal storage of the hashmap may fill up before being
// increased automatically.
// Note: the quotient of these two must be between and different
// from 0 and 1.
HASHMAP_LOADFACTOR_NUMERATOR = 2,
HASHMAP_LOADFACTOR_DENOMINATOR = 3,
HASHMAP_MEMORYPOOL_SIZE = HASHMAP_MIN_CAPACITY * HASHMAP_LOADFACTOR_NUMERATOR / HASHMAP_LOADFACTOR_DENOMINATOR
};
#ifdef USE_HASHMAP_MEMORY_POOL
ObjectPool<Node, HASHMAP_MEMORYPOOL_SIZE> _nodePool;
#endif
Node **_storage; ///< hashtable of size arrsize.
size_type _mask; ///< Capacity of the HashMap minus one; must be a power of two of minus one
size_type _size;
size_type _deleted; ///< Number of deleted elements (_dummyNodes)
HashFunc _hash;
EqualFunc _equal;
/** Default value, returned by the const getVal. */
const Val _defaultVal;
/** Dummy node, used as marker for erased objects. */
#define HASHMAP_DUMMY_NODE ((Node *)1)
#ifdef DEBUG_HASH_COLLISIONS
mutable int _collisions, _lookups, _dummyHits;
#endif
Node *allocNode(const Key &key) {
#ifdef USE_HASHMAP_MEMORY_POOL
return new (_nodePool) Node(key);
#else
return new Node(key);
#endif
}
void freeNode(Node *node) {
if (node && node != HASHMAP_DUMMY_NODE)
#ifdef USE_HASHMAP_MEMORY_POOL
_nodePool.deleteChunk(node);
#else
delete node;
#endif
}
void assign(const HM_t &map);
size_type lookup(const Key &key) const;
size_type lookupAndCreateIfMissing(const Key &key);
void expandStorage(size_type newCapacity);
template<class T> friend class IteratorImpl;
/**
* Simple HashMap iterator implementation.
*/
template<class NodeType>
class IteratorImpl {
friend class HashMap;
#if defined(__INTEL_COMPILER)
template<class T> friend class Common::IteratorImpl;
#else
template<class T> friend class IteratorImpl;
#endif
protected:
typedef const HashMap hashmap_t;
size_type _idx;
hashmap_t *_hashmap;
protected:
IteratorImpl(size_type idx, hashmap_t *hashmap) : _idx(idx), _hashmap(hashmap) {}
NodeType *deref() const {
assert(_hashmap != 0);
assert(_idx <= _hashmap->_mask);
Node *node = _hashmap->_storage[_idx];
assert(node != 0);
assert(node != HASHMAP_DUMMY_NODE);
return node;
}
public:
IteratorImpl() : _idx(0), _hashmap(0) {}
template<class T>
IteratorImpl(const IteratorImpl<T> &c) : _idx(c._idx), _hashmap(c._hashmap) {}
NodeType &operator*() const { return *deref(); }
NodeType *operator->() const { return deref(); }
bool operator==(const IteratorImpl &iter) const { return _idx == iter._idx && _hashmap == iter._hashmap; }
bool operator!=(const IteratorImpl &iter) const { return !(*this == iter); }
IteratorImpl &operator++() {
assert(_hashmap);
do {
_idx++;
} while (_idx <= _hashmap->_mask && (_hashmap->_storage[_idx] == 0 || _hashmap->_storage[_idx] == HASHMAP_DUMMY_NODE));
if (_idx > _hashmap->_mask)
_idx = (size_type)-1;
return *this;
}
IteratorImpl operator++(int) {
IteratorImpl old = *this;
operator ++();
return old;
}
};
public:
typedef IteratorImpl<Node> iterator;
typedef IteratorImpl<const Node> const_iterator;
HashMap();
HashMap(const HM_t &map);
~HashMap();
HM_t &operator=(const HM_t &map) {
if (this == &map)
return *this;
// Remove the previous content and ...
clear();
delete[] _storage;
// ... copy the new stuff.
assign(map);
return *this;
}
bool contains(const Key &key) const;
Val &operator[](const Key &key);
const Val &operator[](const Key &key) const;
Val &getVal(const Key &key);
const Val &getVal(const Key &key) const;
const Val &getVal(const Key &key, const Val &defaultVal) const;
void setVal(const Key &key, const Val &val);
void clear(bool shrinkArray = 0);
void erase(iterator entry);
void erase(const Key &key);
size_type size() const { return _size; }
iterator begin() {
// Find and return the first non-empty entry
for (size_type ctr = 0; ctr <= _mask; ++ctr) {
if (_storage[ctr] && _storage[ctr] != HASHMAP_DUMMY_NODE)
return iterator(ctr, this);
}
return end();
}
iterator end() {
return iterator((size_type)-1, this);
}
const_iterator begin() const {
// Find and return the first non-empty entry
for (size_type ctr = 0; ctr <= _mask; ++ctr) {
if (_storage[ctr] && _storage[ctr] != HASHMAP_DUMMY_NODE)
return const_iterator(ctr, this);
}
return end();
}
const_iterator end() const {
return const_iterator((size_type)-1, this);
}
iterator find(const Key &key) {
size_type ctr = lookup(key);
if (_storage[ctr])
return iterator(ctr, this);
return end();
}
const_iterator find(const Key &key) const {
size_type ctr = lookup(key);
if (_storage[ctr])
return const_iterator(ctr, this);
return end();
}
// TODO: insert() method?
bool empty() const {
return (_size == 0);
}
};
//-------------------------------------------------------
// HashMap functions
/**
* Base constructor, creates an empty hashmap.
*/
template<class Key, class Val, class HashFunc, class EqualFunc>
HashMap<Key, Val, HashFunc, EqualFunc>::HashMap() : _defaultVal() {
_mask = HASHMAP_MIN_CAPACITY - 1;
_storage = new Node *[HASHMAP_MIN_CAPACITY];
assert(_storage != NULL);
memset(_storage, 0, HASHMAP_MIN_CAPACITY * sizeof(Node *));
_size = 0;
_deleted = 0;
#ifdef DEBUG_HASH_COLLISIONS
_collisions = 0;
_lookups = 0;
_dummyHits = 0;
#endif
}
/**
* Copy constructor, creates a full copy of the given hashmap.
* We must provide a custom copy constructor as we use pointers
* to heap buffers for the internal storage.
*/
template<class Key, class Val, class HashFunc, class EqualFunc>
HashMap<Key, Val, HashFunc, EqualFunc>::HashMap(const HM_t &map) :
_defaultVal() {
#ifdef DEBUG_HASH_COLLISIONS
_collisions = 0;
_lookups = 0;
_dummyHits = 0;
#endif
assign(map);
}
/**
* Destructor, frees all used memory.
*/
template<class Key, class Val, class HashFunc, class EqualFunc>
HashMap<Key, Val, HashFunc, EqualFunc>::~HashMap() {
for (size_type ctr = 0; ctr <= _mask; ++ctr)
freeNode(_storage[ctr]);
delete[] _storage;
#ifdef DEBUG_HASH_COLLISIONS
extern void updateHashCollisionStats(int, int, int, int, int);
updateHashCollisionStats(_collisions, _dummyHits, _lookups, _mask+1, _size);
#endif
}
/**
* Internal method for assigning the content of another HashMap
* to this one.
*
* @note We do *not* deallocate the previous storage here -- the caller is
* responsible for doing that!
*/
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::assign(const HM_t &map) {
_mask = map._mask;
_storage = new Node *[_mask+1];
assert(_storage != NULL);
memset(_storage, 0, (_mask+1) * sizeof(Node *));
// Simply clone the map given to us, one by one.
_size = 0;
_deleted = 0;
for (size_type ctr = 0; ctr <= _mask; ++ctr) {
if (map._storage[ctr] == HASHMAP_DUMMY_NODE) {
_storage[ctr] = HASHMAP_DUMMY_NODE;
_deleted++;
} else if (map._storage[ctr] != NULL) {
_storage[ctr] = allocNode(map._storage[ctr]->_key);
_storage[ctr]->_value = map._storage[ctr]->_value;
_size++;
}
}
// Perform a sanity check (to help track down hashmap corruption)
assert(_size == map._size);
assert(_deleted == map._deleted);
}
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::clear(bool shrinkArray) {
for (size_type ctr = 0; ctr <= _mask; ++ctr) {
freeNode(_storage[ctr]);
_storage[ctr] = NULL;
}
#ifdef USE_HASHMAP_MEMORY_POOL
_nodePool.freeUnusedPages();
#endif
if (shrinkArray && _mask >= HASHMAP_MIN_CAPACITY) {
delete[] _storage;
_mask = HASHMAP_MIN_CAPACITY;
_storage = new Node *[HASHMAP_MIN_CAPACITY];
assert(_storage != NULL);
memset(_storage, 0, HASHMAP_MIN_CAPACITY * sizeof(Node *));
}
_size = 0;
_deleted = 0;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(size_type newCapacity) {
assert(newCapacity > _mask+1);
#ifndef RELEASE_BUILD
const size_type old_size = _size;
#endif
const size_type old_mask = _mask;
Node **old_storage = _storage;
// allocate a new array
_size = 0;
_deleted = 0;
_mask = newCapacity - 1;
_storage = new Node *[newCapacity];
assert(_storage != NULL);
memset(_storage, 0, newCapacity * sizeof(Node *));
// rehash all the old elements
for (size_type ctr = 0; ctr <= old_mask; ++ctr) {
if (old_storage[ctr] == NULL || old_storage[ctr] == HASHMAP_DUMMY_NODE)
continue;
// Insert the element from the old table into the new table.
// Since we know that no key exists twice in the old table, we
// can do this slightly better than by calling lookup, since we
// don't have to call _equal().
const size_type hash = _hash(old_storage[ctr]->_key);
size_type idx = hash & _mask;
for (size_type perturb = hash; _storage[idx] != NULL && _storage[idx] != HASHMAP_DUMMY_NODE; perturb >>= HASHMAP_PERTURB_SHIFT) {
idx = (5 * idx + perturb + 1) & _mask;
}
_storage[idx] = old_storage[ctr];
_size++;
}
#ifndef RELEASE_BUILD
// Perform a sanity check: Old number of elements should match the new one!
// This check will fail if some previous operation corrupted this hashmap.
assert(_size == old_size);
#endif
delete[] old_storage;
return;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
typename HashMap<Key, Val, HashFunc, EqualFunc>::size_type HashMap<Key, Val, HashFunc, EqualFunc>::lookup(const Key &key) const {
const size_type hash = _hash(key);
size_type ctr = hash & _mask;
for (size_type perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
if (_storage[ctr] == NULL)
break;
if (_storage[ctr] == HASHMAP_DUMMY_NODE) {
#ifdef DEBUG_HASH_COLLISIONS
_dummyHits++;
#endif
} else if (_equal(_storage[ctr]->_key, key))
break;
ctr = (5 * ctr + perturb + 1) & _mask;
#ifdef DEBUG_HASH_COLLISIONS
_collisions++;
#endif
}
#ifdef DEBUG_HASH_COLLISIONS
_lookups++;
debug("collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d",
_collisions, _dummyHits, _lookups, ((double) _collisions / (double)_lookups),
(const void *)this, _mask+1, _size);
#endif
return ctr;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
typename HashMap<Key, Val, HashFunc, EqualFunc>::size_type HashMap<Key, Val, HashFunc, EqualFunc>::lookupAndCreateIfMissing(const Key &key) {
const size_type hash = _hash(key);
size_type ctr = hash & _mask;
const size_type NONE_FOUND = _mask + 1;
size_type first_free = NONE_FOUND;
bool found = false;
for (size_type perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
if (_storage[ctr] == NULL)
break;
if (_storage[ctr] == HASHMAP_DUMMY_NODE) {
#ifdef DEBUG_HASH_COLLISIONS
_dummyHits++;
#endif
if (first_free != _mask + 1)
first_free = ctr;
} else if (_equal(_storage[ctr]->_key, key)) {
found = true;
break;
}
ctr = (5 * ctr + perturb + 1) & _mask;
#ifdef DEBUG_HASH_COLLISIONS
_collisions++;
#endif
}
#ifdef DEBUG_HASH_COLLISIONS
_lookups++;
debug("collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d",
_collisions, _dummyHits, _lookups, ((double) _collisions / (double)_lookups),
(const void *)this, _mask+1, _size);
#endif
if (!found && first_free != _mask + 1)
ctr = first_free;
if (!found) {
if (_storage[ctr])
_deleted--;
_storage[ctr] = allocNode(key);
assert(_storage[ctr] != NULL);
_size++;
// Keep the load factor below a certain threshold.
// Deleted nodes are also counted
size_type capacity = _mask + 1;
if ((_size + _deleted) * HASHMAP_LOADFACTOR_DENOMINATOR >
capacity * HASHMAP_LOADFACTOR_NUMERATOR) {
capacity = capacity < 500 ? (capacity * 4) : (capacity * 2);
expandStorage(capacity);
ctr = lookup(key);
assert(_storage[ctr] != NULL);
}
}
return ctr;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
bool HashMap<Key, Val, HashFunc, EqualFunc>::contains(const Key &key) const {
size_type ctr = lookup(key);
return (_storage[ctr] != NULL);
}
template<class Key, class Val, class HashFunc, class EqualFunc>
Val &HashMap<Key, Val, HashFunc, EqualFunc>::operator[](const Key &key) {
return getVal(key);
}
template<class Key, class Val, class HashFunc, class EqualFunc>
const Val &HashMap<Key, Val, HashFunc, EqualFunc>::operator[](const Key &key) const {
return getVal(key);
}
template<class Key, class Val, class HashFunc, class EqualFunc>
Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) {
size_type ctr = lookupAndCreateIfMissing(key);
assert(_storage[ctr] != NULL);
return _storage[ctr]->_value;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) const {
return getVal(key, _defaultVal);
}
template<class Key, class Val, class HashFunc, class EqualFunc>
const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key, const Val &defaultVal) const {
size_type ctr = lookup(key);
if (_storage[ctr] != NULL)
return _storage[ctr]->_value;
else
return defaultVal;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::setVal(const Key &key, const Val &val) {
size_type ctr = lookupAndCreateIfMissing(key);
assert(_storage[ctr] != NULL);
_storage[ctr]->_value = val;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::erase(iterator entry) {
// Check whether we have a valid iterator
assert(entry._hashmap == this);
const size_type ctr = entry._idx;
assert(ctr <= _mask);
Node * const node = _storage[ctr];
assert(node != NULL);
assert(node != HASHMAP_DUMMY_NODE);
// If we remove a key, we replace it with a dummy node.
freeNode(node);
_storage[ctr] = HASHMAP_DUMMY_NODE;
_size--;
_deleted++;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::erase(const Key &key) {
size_type ctr = lookup(key);
if (_storage[ctr] == NULL)
return;
// If we remove a key, we replace it with a dummy node.
freeNode(_storage[ctr]);
_storage[ctr] = HASHMAP_DUMMY_NODE;
_size--;
_deleted++;
return;
}
#undef HASHMAP_DUMMY_NODE
} // End of namespace Common
#endif

View File

@@ -0,0 +1,181 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "memorypool.h"
#include "common/util.h"
namespace Common {
enum {
INITIAL_CHUNKS_PER_PAGE = 8
};
static size_t adjustChunkSize(size_t chunkSize) {
// You must at least fit the pointer in the node (technically unneeded considering the next rounding statement)
chunkSize = MAX(chunkSize, sizeof(void *));
// There might be an alignment problem on some platforms when trying to load a void* on a non natural boundary
// so we round to the next sizeof(void *)
chunkSize = (chunkSize + sizeof(void *) - 1) & (~(sizeof(void *) - 1));
return chunkSize;
}
MemoryPool::MemoryPool(size_t chunkSize)
: _chunkSize(adjustChunkSize(chunkSize)) {
_next = nullptr;
_chunksPerPage = INITIAL_CHUNKS_PER_PAGE;
}
MemoryPool::~MemoryPool() {
#if 0
freeUnusedPages();
if (!_pages.empty())
warning("Memory leak found in pool");
#endif
for (size_t i = 0; i < _pages.size(); ++i)
::free(_pages[i].start);
}
void MemoryPool::allocPage() {
Page page;
// Allocate a new page
page.numChunks = _chunksPerPage;
assert(page.numChunks * _chunkSize < 16*1024*1024); // Refuse to allocate pages bigger than 16 MB
page.start = ::malloc(page.numChunks * _chunkSize);
assert(page.start);
_pages.push_back(page);
// Next time, we'll allocate a page twice as big as this one.
_chunksPerPage *= 2;
// Add the page to the pool of free chunk
addPageToPool(page);
}
void MemoryPool::addPageToPool(const Page &page) {
// Add all chunks of the new page to the linked list (pool) of free chunks
void *current = page.start;
for (size_t i = 1; i < page.numChunks; ++i) {
void *next = (byte *)current + _chunkSize;
*(void **)current = next;
current = next;
}
// Last chunk points to the old _next
*(void **)current = _next;
// From now on, the first free chunk is the first chunk of the new page
_next = page.start;
}
void *MemoryPool::allocChunk() {
// No free chunks left? Allocate a new page
if (!_next)
allocPage();
assert(_next);
void *result = _next;
_next = *(void **)result;
return result;
}
void MemoryPool::freeChunk(void *ptr) {
// Add the chunk back to (the start of) the list of free chunks
*(void **)ptr = _next;
_next = ptr;
}
// Technically not compliant C++ to compare unrelated pointers. In practice...
bool MemoryPool::isPointerInPage(void *ptr, const Page &page) {
return (ptr >= page.start) && (ptr < (char *)page.start + page.numChunks * _chunkSize);
}
void MemoryPool::freeUnusedPages() {
//std::sort(_pages.begin(), _pages.end());
Array<size_t> numberOfFreeChunksPerPage;
numberOfFreeChunksPerPage.resize(_pages.size());
for (size_t i = 0; i < numberOfFreeChunksPerPage.size(); ++i) {
numberOfFreeChunksPerPage[i] = 0;
}
// Compute for each page how many chunks in it are still in use.
void *iterator = _next;
while (iterator) {
// TODO: This should be a binary search (requiring us to keep _pages sorted)
for (size_t i = 0; i < _pages.size(); ++i) {
if (isPointerInPage(iterator, _pages[i])) {
++numberOfFreeChunksPerPage[i];
break;
}
}
iterator = *(void **)iterator;
}
// Free all pages which are not in use.
size_t freedPagesCount = 0;
for (size_t i = 0; i < _pages.size(); ++i) {
if (numberOfFreeChunksPerPage[i] == _pages[i].numChunks) {
// Remove all chunks of this page from the list of free chunks
void **iter2 = &_next;
while (*iter2) {
if (isPointerInPage(*iter2, _pages[i]))
*iter2 = **(void ***)iter2;
else
iter2 = *(void ***)iter2;
}
::free(_pages[i].start);
++freedPagesCount;
_pages[i].start = nullptr;
}
}
// debug("freed %d pages out of %d", (int)freedPagesCount, (int)_pages.size());
// Remove all now unused pages
size_t newSize = 0;
for (size_t i = 0; i < _pages.size(); ++i) {
if (_pages[i].start != nullptr) {
if (newSize != i)
_pages[newSize] = _pages[i];
++newSize;
}
}
_pages.resize(newSize);
// Reset _chunksPerPage
_chunksPerPage = INITIAL_CHUNKS_PER_PAGE;
for (size_t i = 0; i < _pages.size(); ++i) {
if (_chunksPerPage < _pages[i].numChunks)
_chunksPerPage = _pages[i].numChunks;
}
}
} // End of namespace Common

View File

@@ -0,0 +1,161 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COMMON_MEMORYPOOL_H
#define COMMON_MEMORYPOOL_H
#include "common/array.h"
namespace Common {
/**
* This class provides a pool of memory 'chunks' of identical size.
* The size of a chunk is determined when creating the memory pool.
*
* Using a memory pool may yield better performance and memory usage
* when allocating and deallocating many memory blocks of equal size.
* E.g. the Common::String class uses a memory pool for the refCount
* variables (each the size of an int) it allocates for each string
* instance.
*/
class MemoryPool {
protected:
MemoryPool(const MemoryPool&);
MemoryPool& operator=(const MemoryPool&);
struct Page {
void *start;
size_t numChunks;
};
const size_t _chunkSize;
Array<Page> _pages;
void *_next;
size_t _chunksPerPage;
void allocPage();
void addPageToPool(const Page &page);
bool isPointerInPage(void *ptr, const Page &page);
public:
/**
* Constructor for a memory pool with the given chunk size.
* @param chunkSize the chunk size of this memory pool
*/
explicit MemoryPool(size_t chunkSize);
~MemoryPool();
/**
* Allocate a new chunk from the memory pool.
*/
void *allocChunk();
/**
* Return a chunk to the memory pool. The given pointer must have
* been obtained from calling the allocChunk() method of the very
* same MemoryPool instance. Passing any other pointer (e.g. to
* a chunk from another MemoryPool, or a malloc'ed memory block)
* will lead to undefined behavior and may result in a crash (if
* you are lucky) or in silent data corruption.
*/
void freeChunk(void *ptr);
/**
* Perform garbage collection. The memory pool stores all the
* chunks it manages in memory 'pages' obtained via the classic
* memory allocation APIs (i.e. malloc/free). Ordinarily, once
* a page has been allocated, it won't be released again during
* the life time of the memory pool. The exception is when this
* method is called.
*/
void freeUnusedPages();
/**
* Return the chunk size used by this memory pool.
*/
size_t getChunkSize() const { return _chunkSize; }
};
/**
* This is a memory pool which already contains in itself some storage
* space for a fixed number of chunks. Thus if the memory pool is only
* lightly used, no malloc() calls have to be made at all.
*/
template<size_t CHUNK_SIZE, size_t NUM_INTERNAL_CHUNKS = 32>
class FixedSizeMemoryPool : public MemoryPool {
private:
enum {
REAL_CHUNK_SIZE = (CHUNK_SIZE + sizeof(void *) - 1) & (~(sizeof(void *) - 1))
};
byte _storage[NUM_INTERNAL_CHUNKS * REAL_CHUNK_SIZE];
public:
FixedSizeMemoryPool() : MemoryPool(CHUNK_SIZE) {
assert(REAL_CHUNK_SIZE == _chunkSize);
// Insert some static storage
Page internalPage = { _storage, NUM_INTERNAL_CHUNKS };
addPageToPool(internalPage);
}
};
// Ensure NUM_INTERNAL_CHUNKS == 0 results in a compile error
template<size_t CHUNK_SIZE>
class FixedSizeMemoryPool<CHUNK_SIZE,0> : public MemoryPool {
public:
FixedSizeMemoryPool() : MemoryPool(CHUNK_SIZE) {}
};
/**
* A memory pool for C++ objects.
*/
template<class T, size_t NUM_INTERNAL_CHUNKS = 32>
class ObjectPool : public FixedSizeMemoryPool<sizeof(T), NUM_INTERNAL_CHUNKS> {
public:
/**
* Return the memory chunk used as storage for the given object back
* to the pool, after calling its destructor.
*/
void deleteChunk(T *ptr) {
ptr->~T();
this->freeChunk(ptr);
}
};
} // End of namespace Common
/**
* A custom placement new operator, using an arbitrary MemoryPool.
*
* This *should* work with all C++ implementations, but may not.
*
* For details on using placement new for custom allocators, see e.g.
* <https://isocpp.org/wiki/faq/dtors#memory-pools>
*/
inline void *operator new(size_t nbytes, Common::MemoryPool &pool) {
assert(nbytes <= pool.getChunkSize());
return pool.allocChunk();
}
inline void operator delete(void *p, Common::MemoryPool &pool) {
pool.freeChunk(p);
}
#endif

View File

@@ -0,0 +1,31 @@
ifdef USE_ZLIB
MODULE := devtools/create_titanic
MODULE_OBJS := \
create_titanic_dat.o \
hashmap.o \
memorypool.o \
script_preresponses.o \
script_quotes.o \
script_ranges.o \
script_responses.o \
script_states.o \
base-str.o \
str.o \
tag_maps.o \
winexe.o \
winexe_pe.o \
zlib.o
# Set the name of the executable
TOOL_EXECUTABLE := create_titanic
TOOL_CFLAGS := $(ZLIB_CFLAGS)
TOOL_LIBS := $(ZLIB_LIBS)
# Include common rules
include $(srcdir)/rules.mk
endif

View File

@@ -0,0 +1,257 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "file.h"
#include "script_preresponses.h"
extern void writeEntryHeader(const char *name, uint offset, uint size);
static const PreResponse BARBOT_PRERESPONSES_EN[] = {
{ 0x0CA02, 0x3D102 },
{ 0x0CA68, 0x3D102 },
{ 0x0C9DA, 0x3D102 },
{ 0x0CA6A, 0x3D103 },
{ 0x0C922, 0x3D099 },
{ 0x0C97C, 0x3D099 },
{ 0x0CA0B, 0x3D099 },
{ 0x0CA72, 0x3D099 },
{ 0x0CA0E, 0x3D107 },
{ 0x0CA73, 0x3D107 },
{ 0x0CA12, 0x3D108 },
{ 0x0CA1C, 0x3D10E },
{ 0x0CA83, 0x3D10E },
{ 0x0CA1F, 0x3D110 },
{ 0x0CA86, 0x3D110 },
{ 0x0CA23, 0x3D112 },
{ 0x0CA8A, 0x3D112 },
{ 0x0CA92, 0x3D122 },
{ 0x0CA30, 0x3D116 },
{ 0x0CA96, 0x3D116 },
{ 0x0CA36, 0x3D117 },
{ 0x0C9FC, 0x3D117 },
{ 0x0CA9B, 0x3D117 },
{ 0x0CA63, 0x3D117 },
{ 0x0CA38, 0x3D11B },
{ 0x0CA15, 0x3D109 },
{ 0x0CA7B, 0x3D109 },
{ 0x0CA2E, 0x3D115 },
{ 0x0CA94, 0x3D115 },
{ 0x0CA5C, 0x3D115 },
{ 0x0CA21, 0x3D111 },
{ 0x0CA88, 0x3D111 },
{ 0x0CA2A, 0x3D114 },
{ 0x0CA28, 0x3D119 },
{ 0x0CA8E, 0x3D119 },
{ 0x0CA17, 0x3D10B },
{ 0x0CA7D, 0x3D10B },
{ 0x0CA4C, 0x3D10B },
{ 0x0CA06, 0x3D105 },
{ 0x0CA6C, 0x3D105 },
{ 0x0CA0A, 0x3D106 },
{ 0x0CA70, 0x3D106 },
{ 0x0CA19, 0x3D10C },
{ 0x0CA7F, 0x3D10C },
{ 0x0C9FF, 0x3D101 },
{ 0x0CA65, 0x3D101 },
{ 0x00000, 0x00000 }
};
static const PreResponse BARBOT_PRERESPONSES_DE[] = {
{ 0x0ca11, 0x3d102 },
{ 0x0ca77, 0x3d102 },
{ 0x0c9e9, 0x3d102 },
{ 0x0ca79, 0x3d103 },
{ 0x0c931, 0x3d099 },
{ 0x0c98b, 0x3d099 },
{ 0x0ca1a, 0x3d099 },
{ 0x0ca81, 0x3d099 },
{ 0x0ca1d, 0x3d107 },
{ 0x0ca82, 0x3d107 },
{ 0x0ca21, 0x3d108 },
{ 0x0ca2b, 0x3d10e },
{ 0x0ca92, 0x3d10e },
{ 0x0ca2e, 0x3d110 },
{ 0x0ca95, 0x3d110 },
{ 0x0ca32, 0x3d112 },
{ 0x0ca99, 0x3d112 },
{ 0x0caa1, 0x3d122 },
{ 0x0ca3f, 0x3d116 },
{ 0x0caa5, 0x3d116 },
{ 0x0ca45, 0x3d117 },
{ 0x0ca0b, 0x3d117 },
{ 0x0caaa, 0x3d117 },
{ 0x0ca72, 0x3d117 },
{ 0x0ca47, 0x3d11b },
{ 0x0ca24, 0x3d109 },
{ 0x0ca8a, 0x3d109 },
{ 0x0ca3d, 0x3d115 },
{ 0x0caa3, 0x3d115 },
{ 0x0ca6b, 0x3d115 },
{ 0x0ca30, 0x3d111 },
{ 0x0ca97, 0x3d111 },
{ 0x0ca39, 0x3d114 },
{ 0x0ca37, 0x3d119 },
{ 0x0ca9d, 0x3d119 },
{ 0x0ca26, 0x3d10b },
{ 0x0ca8c, 0x3d10b },
{ 0x0ca5b, 0x3d10b },
{ 0x0ca15, 0x3d105 },
{ 0x0ca7b, 0x3d105 },
{ 0x0ca19, 0x3d106 },
{ 0x0ca7f, 0x3d106 },
{ 0x0ca28, 0x3d10c },
{ 0x0ca8e, 0x3d10c },
{ 0x0ca0e, 0x3d101 },
{ 0x0ca74, 0x3d101 },
{ 0x00000, 0x00000 }
};
static const PreResponse BELLBOT_PRERESPONSES_EN[] = {
{ 0x052DC, 0x30D40 },
{ 0x054E9, 0x30D40 },
{ 0x054EC, 0x30D40 },
{ 0x054F0, 0x30D40 },
{ 0x0532C, 0x31625 },
{ 0x05330, 0x31625 },
{ 0x05368, 0x31625 },
{ 0x05369, 0x31625 },
{ 0x0536A, 0x31625 },
{ 0x0536B, 0x31625 },
{ 0x0536C, 0x31625 },
{ 0x0536D, 0x31625 },
{ 0x053A4, 0x31625 },
{ 0x0558A, 0x31625 },
{ 0x05485, 0x31625 },
{ 0x04EE7, 0x31625 },
{ 0x04EE8, 0x31625 },
{ 0x0530A, 0x31625 },
{ 0x0530B, 0x31625 },
{ 0x053F6, 0x31625 },
{ 0x053F7, 0x31625 },
{ 0x053F8, 0x31625 },
{ 0x053F9, 0x31625 },
{ 0x053FA, 0x31625 },
{ 0x053FB, 0x31625 },
{ 0x053FC, 0x31625 },
{ 0x053FD, 0x31625 },
{ 0x0556B, 0x31041 },
{ 0x05499, 0x30D40 },
{ 0x053E9, 0x30E01 },
{ 0x053EB, 0x30E01 },
{ 0x053EC, 0x30E01 },
{ 0x053ED, 0x30E01 },
{ 0x053EE, 0x30E01 },
{ 0x053EF, 0x30E01 },
{ 0x053F0, 0x30E01 },
{ 0x053F1, 0x30E01 },
{ 0x053F2, 0x30E01 },
{ 0x053EA, 0x30E01 },
{ 0x05441, 0x30F00 },
{ 0x05444, 0x30F00 },
{ 0x05445, 0x30F00 },
{ 0x05443, 0x30F00 },
{ 0x05446, 0x30F00 },
{ 0x05447, 0x30F00 },
{ 0x05448, 0x30F00 },
{ 0x05449, 0x30F00 },
{ 0x0544A, 0x30F00 },
{ 0x0544B, 0x30F00 },
{ 0x05442, 0x30F00 },
{ 0x0527C, 0x315C8 },
{ 0x00000, 0x00000 }
};
static const PreResponse BELLBOT_PRERESPONSES_DE[] = {
{ 0x052e2, 0x30d40 },
{ 0x054f1, 0x30d40 },
{ 0x054f4, 0x30d40 },
{ 0x054f8, 0x30d40 },
{ 0x05332, 0x31625 },
{ 0x05336, 0x31625 },
{ 0x0536e, 0x31625 },
{ 0x0536f, 0x31625 },
{ 0x05370, 0x31625 },
{ 0x05371, 0x31625 },
{ 0x05372, 0x31625 },
{ 0x05373, 0x31625 },
{ 0x053ab, 0x31625 },
{ 0x05592, 0x31625 },
{ 0x0548c, 0x31625 },
{ 0x04ee7, 0x31625 },
{ 0x04ee8, 0x31625 },
{ 0x05310, 0x31625 },
{ 0x05311, 0x31625 },
{ 0x053fd, 0x31625 },
{ 0x053fe, 0x31625 },
{ 0x053ff, 0x31625 },
{ 0x05400, 0x31625 },
{ 0x05401, 0x31625 },
{ 0x05402, 0x31625 },
{ 0x05403, 0x31625 },
{ 0x05404, 0x31625 },
{ 0x05573, 0x31041 },
{ 0x054a1, 0x30d40 },
{ 0x053f0, 0x30e01 },
{ 0x053f2, 0x30e01 },
{ 0x053f3, 0x30e01 },
{ 0x053f4, 0x30e01 },
{ 0x053f5, 0x30e01 },
{ 0x053f6, 0x30e01 },
{ 0x053f7, 0x30e01 },
{ 0x053f8, 0x30e01 },
{ 0x053f9, 0x30e01 },
{ 0x053f1, 0x30e01 },
{ 0x05448, 0x30f00 },
{ 0x0544b, 0x30f00 },
{ 0x0544c, 0x30f00 },
{ 0x0544a, 0x30f00 },
{ 0x0544d, 0x30f00 },
{ 0x0544e, 0x30f00 },
{ 0x0544f, 0x30f00 },
{ 0x05450, 0x30f00 },
{ 0x05451, 0x30f00 },
{ 0x05452, 0x30f00 },
{ 0x05449, 0x30f00 },
{ 0x05282, 0x315c8 },
{ 0x00000, 0x00000 }
};
void writeScriptPreResponses(const char *name, const PreResponse *states) {
outputFile->seek(dataOffset);
for (; states->_src; ++states) {
outputFile->writeLong(states->_src);
outputFile->writeLong(states->_dest);
}
uint size = outputFile->size() - dataOffset;
writeEntryHeader(name, dataOffset, size);
dataOffset += size;
}
void writeAllScriptPreResponses() {
writeScriptPreResponses("PreResponses/Barbot", BARBOT_PRERESPONSES_EN);
writeScriptPreResponses("PreResponses/Barbot/DE", BARBOT_PRERESPONSES_DE);
writeScriptPreResponses("PreResponses/Bellbot", BELLBOT_PRERESPONSES_EN);
writeScriptPreResponses("PreResponses/Bellbot/DE", BELLBOT_PRERESPONSES_DE);
}

View File

@@ -0,0 +1,35 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COMMON_SCRIPT_PRERESPONSES_H
#define COMMON_SCRIPT_PRERESPONSES_H
#include "common/scummsys.h"
struct PreResponse {
uint _src;
uint _dest;
};
extern void writeAllScriptPreResponses();
extern uint dataOffset;
#endif

View File

@@ -0,0 +1,474 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "file.h"
#include "script_quotes.h"
extern void writeEntryHeader(const char *name, uint offset, uint size);
static const ScriptQuote BARBOT_QUOTES[] = {
{ 0x0003d722, 0x0003d372, 0x0000001e },
{ 0x0003d722, 0x0003d372, 0x00000032 },
{ 0x0003d722, 0x0003d372, 0x00000046 },
{ 0x00000008, 0x00000000, 0x0003D372 },
{ 0x00000007, 0x00000000, 0x0003D72B },
{ 0x00000004, 0x00000000, 0x0003D722 },
{ 0x00000006, 0x00000000, 0x0003D264 },
{ 0x00000005, 0x00000000, 0x0003D72F },
{ 0x00000001, 0x00000032, 0x00000001 },
{ 0x00000002, 0x00000032, 0x00000001 },
{ 0x00000003, 0x00000032, 0x00000001 },
{ 0x00000010, 0x54524156, 0x0003D2B1 },
{ 0x00000010, 0x0000003C, 0x00000000 },
{ 0x00000011, 0x00000000, 0x0003D484 },
{ 0x00000015, 0x00000032, 0x0003D2B2 },
{ 0x00000012, 0x00000042, 0x0003D499 },
{ 0x00000013, 0x00000021, 0x0003D31E },
{ 0x0000001D, 0x00000021, 0x0003D31E },
{ 0x00000014, 0x00000042, 0x0003D49E },
{ 0x00000016, 0x0000003C, 0x0003D2B6 },
{ 0x00000017, 0x00000028, 0x0003D2B5 },
{ 0x00000018, 0x00000000, 0x0003D35E },
{ 0x00000019, 0x00000000, 0x0003D35E },
{ 0x0000001A, 0x0000003C, 0x0003D38B },
{ 0x0000001B, 0x00000000, 0x0003D2F8 },
{ 0x00000009, 0x00000019, 0x0003D326 },
{ 0x0000000A, 0x00000019, 0x0003D314 },
{ 0x0000000B, 0x00000028, 0x0003D311 },
{ 0x0000001E, 0x00000000, 0x0003D6F2 },
{ 0x0000001F, 0x00000000, 0x0003D26C },
{ 0x0000000C, 0x00000000, 0x0003D2F4 },
{ 0x0000000D, 0x00000000, 0x0003D2F4 },
{ 0x0000000E, 0x00000000, 0x0003D2F4 },
{ 0x0000000F, 0x00000000, 0x0003D2F4 },
{ 0x00000020, 0x00000019, 0x0003D389 },
{ 0x00000021, 0x0000000F, 0x0003D29C },
{ 0x00000022, 0x0000000F, 0x0003D494 },
{ 0x0000001C, 0x00000032, 0x00000000 },
{ 0x00000023, 0x00000000, 0x0003D7F8 },
{ 0x00000024, 0x00000000, 0x0003D7F9 },
{ 0x00000031, 0x00000000, 0x0003D722 },
{ 0x00000032, 0x00000000, 0x0003D722 },
{ 0x00000033, 0x00000000, 0x0003D372 },
{ 0x00000034, 0x00000000, 0x0003D323 },
{ 0x0000003E, 0x00000000, 0x0003D163 },
{ 0x0000003F, 0x00000000, 0x0003D163 },
{ 0x00000040, 0x00000000, 0x0003D163 },
{ 0x00000041, 0x00000000, 0x0003D691 },
{ 0x00000000, 0x00000000, 0x00000000 }
};
static const ScriptQuote BELLBOT_QUOTES[] = {
{ 0x000313d6, 0x000313d7, 0x0000001e },
{ 0x000313d6, 0x000313d7, 0x00000032 },
{ 0x000313d6, 0x000313d7, 0x00000046 },
{ 0x000313a1, 0x000313ae, 0x0000003c },
{ 0x00000008, 0x00000000, 0x00031116 },
{ 0x00000007, 0x00000000, 0x00031447 },
{ 0x00000006, 0x00000000, 0x000310F9 },
{ 0x00000005, 0x00000000, 0x000313A1 },
{ 0x00000001, 0x56424144, 0x000313D7 },
{ 0x00000001, 0x52554445, 0x000313D7 },
{ 0x00000001, 0x5052534E, 0x00041EB3 },
{ 0x00000001, 0x424F5953, 0x00041EB3 },
{ 0x00000001, 0x4749524C, 0x00041EB3 },
{ 0x00000001, 0x464F4F44, 0x00041EB3 },
{ 0x00000001, 0x00000032, 0x00041EB1 },
{ 0x0000001C, 0x00000032, 0x00041EB0 },
{ 0x00000010, 0x54524156, 0x000313C6 },
{ 0x00000010, 0x0000003C, 0x00041EB0 },
{ 0x00000011, 0x00000000, 0x0003139E },
{ 0x00000015, 0x00000032, 0x0003139F },
{ 0x00000012, 0x00000042, 0x000313A0 },
{ 0x00000013, 0x00000021, 0x000313A7 },
{ 0x0000001D, 0x00000021, 0x000313A7 },
{ 0x00000014, 0x00000042, 0x000313A4 },
{ 0x0000001B, 0x00000000, 0x0003139B },
{ 0x0000001E, 0x00000000, 0x000313A2 },
{ 0x0000001F, 0x00000000, 0x00030DC0 },
{ 0x0000000C, 0x00000000, 0x000313A9 },
{ 0x0000000D, 0x00000000, 0x000313A9 },
{ 0x0000000E, 0x00000000, 0x000313A8 },
{ 0x0000000F, 0x00000000, 0x000313A8 },
{ 0x00000020, 0x00000019, 0x000313AB },
{ 0x00000021, 0x0000000F, 0x000313AC },
{ 0x00000023, 0x00000000, 0x00031337 },
{ 0x00000024, 0x00000000, 0x0003135A },
{ 0x00000025, 0x00000000, 0x000311AB },
{ 0x00000026, 0x00000000, 0x0003112E },
{ 0x00000030, 0x00000000, 0x0003106C },
{ 0x00000027, 0x424F5953, 0x0003140C },
{ 0x00000027, 0x4749524C, 0x0003140D },
{ 0x00000027, 0x00000000, 0x0003140D },
{ 0x00000028, 0x00000000, 0x00031404 },
{ 0x00000029, 0x00000000, 0x00031405 },
{ 0x0000002A, 0x00000000, 0x00031406 },
{ 0x0000002B, 0x00000000, 0x00031407 },
{ 0x0000002C, 0x00000000, 0x00031408 },
{ 0x0000002D, 0x00000000, 0x00031409 },
{ 0x0000002E, 0x424F5953, 0x0003140A },
{ 0x0000002E, 0x4749524C, 0x0003140B },
{ 0x0000002E, 0x00000000, 0x0003140B },
{ 0x00000032, 0x00000000, 0x000313D6 },
{ 0x00000033, 0x00000000, 0x000313D7 },
{ 0x00000034, 0x00000000, 0x000313D8 },
{ 0x00000035, 0x00000000, 0x0003113D },
{ 0x00000036, 0x00000000, 0x00030DCB },
{ 0x00000031, 0x00000000, 0x00030DB5 },
{ 0x00000037, 0x00000000, 0x000313DD },
{ 0x00000038, 0x00000000, 0x00030EE4 },
{ 0x00000039, 0x00000000, 0x0003160B },
{ 0x0000003A, 0x00000000, 0x000310C4 },
{ 0x0000003B, 0x00000000, 0x000310C5 },
{ 0x0000003C, 0x00000000, 0x0003121C },
{ 0x0000003D, 0x00000000, 0x00031623 },
{ 0x0000003F, 0x00000000, 0x00030D99 },
{ 0x0000003E, 0x00000000, 0x00030D99 },
{ 0x00000040, 0x00000000, 0x000315CE },
{ 0x00000041, 0x00000000, 0x000315DC },
{ 0x00000042, 0x00000000, 0x00031478 },
{ 0x00000043, 0x00000000, 0x00030FC8 },
{ 0x00000044, 0x00000000, 0x0003106D },
{ 0x00000054, 0x00000000, 0x00031514 },
{ 0x00000055, 0x00000000, 0x00031515 },
{ 0x00000056, 0x00000000, 0x000315CF },
{ 0x0000005A, 0x00000000, 0x000310F9 },
{ 0x00000058, 0x00000000, 0x000315DF },
{ 0x0000005B, 0x00000000, 0x00031620 },
{ 0x0000005C, 0x00000000, 0x0003134B },
{ 0x00000059, 0x00000000, 0x0003150F },
{ 0x00000057, 0x00000000, 0x00030D58 },
{ 0x00000045, 0x0000000A, 0x000310C3 },
{ 0x00000046, 0x00000000, 0x00030EAD },
{ 0x00000000, 0x00000000, 0x00000000 }
};
static const ScriptQuote DESKBOT_QUOTES[] = {
{ 0x0003ae0e, 0x0003ae27, 0x0000001e },
{ 0x0003ae0e, 0x0003ae27, 0x00000032 },
{ 0x0003ae0e, 0x0003ae27, 0x00000046 },
{ 0x0003abe1, 0x0003ae4c, 0x0000003c },
{ 0x00000008, 0x00000000, 0x0003ACD0 },
{ 0x00000007, 0x00000000, 0x0003ACDC },
{ 0x00000006, 0x00000000, 0x0003ABF9 },
{ 0x00000005, 0x00000000, 0x0003AD04 },
{ 0x00000001, 0x56424144, 0x0003AE27 },
{ 0x00000001, 0x52554445, 0x0003AE27 },
{ 0x00000001, 0x5052534E, 0x00041EB3 },
{ 0x00000001, 0x464F4F44, 0x00041EB3 },
{ 0x00000001, 0x00000032, 0x00041EB1 },
{ 0x00000002, 0x56424144, 0x0003AE27 },
{ 0x00000002, 0x52554445, 0x0003AE27 },
{ 0x00000002, 0x5052534E, 0x00041EB3 },
{ 0x00000002, 0x464F4F44, 0x00041EB3 },
{ 0x00000002, 0x00000032, 0x00041EB1 },
{ 0x00000003, 0x56424144, 0x0003AE0E },
{ 0x00000003, 0x52554445, 0x0003AE0E },
{ 0x00000003, 0x5052534E, 0x00041EB3 },
{ 0x00000003, 0x464F4F44, 0x00041EB3 },
{ 0x00000003, 0x00000032, 0x00041EB1 },
{ 0x00000010, 0x54524156, 0x0003ACFE },
{ 0x00000010, 0x0000003C, 0x00041EB0 },
{ 0x00000011, 0x00000000, 0x0003ABF9 },
{ 0x00000015, 0x00000032, 0x0003AC70 },
{ 0x00000012, 0x00000042, 0x0003AC7E },
{ 0x00000013, 0x00000021, 0x0003AC70 },
{ 0x0000001D, 0x00000021, 0x0003AC09 },
{ 0x00000014, 0x00000042, 0x0003AE07 },
{ 0x0000001B, 0x00000000, 0x00041EB2 },
{ 0x0000001E, 0x00000000, 0x0003ACC1 },
{ 0x0000001F, 0x00000000, 0x0003AC3E },
{ 0x0000000C, 0x00000000, 0x0003AE4C },
{ 0x0000000D, 0x00000000, 0x0003AE4C },
{ 0x0000000E, 0x00000000, 0x0003AE4B },
{ 0x0000000F, 0x00000000, 0x0003AE4B },
{ 0x00000020, 0x00000019, 0x0003AE24 },
{ 0x00000021, 0x0000000F, 0x0003AE10 },
{ 0x0000001C, 0x00000032, 0x00041EB0 },
{ 0x00000023, 0x00000000, 0x0003AC46 },
{ 0x00000024, 0x00000000, 0x0003AE1F },
{ 0x00000025, 0x00000000, 0x0003AE14 },
{ 0x00000026, 0x00000000, 0x0003AC7B },
{ 0x00000030, 0x00000000, 0x0003AE3D },
{ 0x00000027, 0x424F5953, 0x0003AE5D },
{ 0x00000027, 0x4749524C, 0x0003AE5E },
{ 0x00000027, 0x00000000, 0x0003AE5C },
{ 0x00000028, 0x00000000, 0x0003AE5B },
{ 0x00000029, 0x00000000, 0x0003AE58 },
{ 0x0000002A, 0x00000000, 0x0003AE59 },
{ 0x0000002B, 0x00000000, 0x0003AE5A },
{ 0x0000002C, 0x00000000, 0x0003AE57 },
{ 0x0000002D, 0x00000000, 0x0003AE5C },
{ 0x0000002E, 0x424F5953, 0x0003AE5A },
{ 0x0000002E, 0x4749524C, 0x0003AE5A },
{ 0x0000002E, 0x00000000, 0x0003AE5A },
{ 0x00000032, 0x00000000, 0x0003AE0E },
{ 0x00000033, 0x00000000, 0x0003AE27 },
{ 0x00000034, 0x00000000, 0x0003AE24 },
{ 0x00000035, 0x00000000, 0x0003AE3E },
{ 0x00000037, 0x00000000, 0x0003AE26 },
{ 0x00000038, 0x00000000, 0x0003AEC0 },
{ 0x00000039, 0x00000000, 0x0003AEC1 },
{ 0x0000003A, 0x00000000, 0x0003AC7F },
{ 0x0000003B, 0x00000000, 0x0003ADD5 },
{ 0x0000003C, 0x00000000, 0x0003AEC5 },
{ 0x0000003D, 0x00000000, 0x0003AEC9 },
{ 0x0000003F, 0x00000000, 0x0003ABC5 },
{ 0x0000003E, 0x00000000, 0x0003ABC5 },
{ 0x00000040, 0x00000000, 0x0003AFB0 },
{ 0x00000041, 0x00000000, 0x0003AFDC },
{ 0x00000042, 0x00000000, 0x0003AFB5 },
{ 0x00000043, 0x00000000, 0x0003AFDD },
{ 0x00000044, 0x00000000, 0x0003AFDD },
{ 0x00000045, 0x0000000A, 0x0003AC7E },
{ 0x00000046, 0x00000000, 0x0003AF6E },
{ 0x00000000, 0x00000000, 0x00000000 }
};
static const ScriptQuote DOORBOT_QUOTES[] = {
{ 0x000360bf, 0x000360c0, 0x0000001e },
{ 0x000360bf, 0x000360c0, 0x00000032 },
{ 0x000360bf, 0x000360c0, 0x00000046 },
{ 0x000360c1, 0x000360c2, 0x0000003c },
{ 0x00000008, 0x00000000, 0x00035F14 },
{ 0x00000007, 0x00000000, 0x00035F6F },
{ 0x00000004, 0x00000000, 0x000360BF },
{ 0x00000006, 0x00000000, 0x000360AF },
{ 0x00000005, 0x00000000, 0x000360BC },
{ 0x00000001, 0x56424144, 0x000360C0 },
{ 0x00000001, 0x52554445, 0x000360C0 },
{ 0x00000001, 0x5052534E, 0x00000003 },
{ 0x00000001, 0x464F4F44, 0x00000003 },
{ 0x00000001, 0x00000032, 0x00000001 },
{ 0x00000002, 0x56424144, 0x000360C0 },
{ 0x00000002, 0x52554445, 0x000360C0 },
{ 0x00000002, 0x5052534E, 0x00000003 },
{ 0x00000002, 0x464F4F44, 0x00000003 },
{ 0x00000002, 0x00000032, 0x00000001 },
{ 0x00000003, 0x56424144, 0x000360C0 },
{ 0x00000003, 0x52554445, 0x000360C0 },
{ 0x00000003, 0x5052534E, 0x00000003 },
{ 0x00000003, 0x464F4F44, 0x00000003 },
{ 0x00000003, 0x00000032, 0x00000001 },
{ 0x00000010, 0x54524156, 0x00035F6A },
{ 0x00000010, 0x0000003C, 0x00000000 },
{ 0x00000011, 0x00000000, 0x0003604F },
{ 0x00000015, 0x00000032, 0x00036046 },
{ 0x00000012, 0x00000042, 0x00036057 },
{ 0x00000013, 0x00000021, 0x00035FC8 },
{ 0x0000001D, 0x00000021, 0x00035FC8 },
{ 0x00000014, 0x00000042, 0x00036059 },
{ 0x00000016, 0x0000003C, 0x00035F6E },
{ 0x00000017, 0x00000028, 0x00035F6D },
{ 0x00000018, 0x00000000, 0x00035F68 },
{ 0x00000019, 0x00000000, 0x00035F68 },
{ 0x0000001A, 0x0000003C, 0x00035F67 },
{ 0x0000001B, 0x00000000, 0x00035FA0 },
{ 0x00000009, 0x00000019, 0x00035FD3 },
{ 0x0000000A, 0x00000019, 0x00036051 },
{ 0x0000000B, 0x00000028, 0x00035FC4 },
{ 0x0000001E, 0x00000000, 0x00035F5C },
{ 0x0000001F, 0x00000000, 0x00035F5C },
{ 0x0000000C, 0x00000000, 0x00035F9D },
{ 0x0000000D, 0x00000000, 0x00035F9D },
{ 0x0000000E, 0x00000000, 0x00035F9C },
{ 0x0000000F, 0x00000000, 0x00035F9C },
{ 0x00000020, 0x00000019, 0x00035FFF },
{ 0x00000021, 0x0000000F, 0x00035F59 },
{ 0x00000022, 0x0000000F, 0x00036055 },
{ 0x0000001C, 0x00000032, 0x00000000 },
{ 0x00000023, 0x00000000, 0x000360C3 },
{ 0x00000024, 0x00000000, 0x00035F5B },
{ 0x00000025, 0x00000000, 0x00035EFE },
{ 0x00000026, 0x00000000, 0x00035F03 },
{ 0x0000002C, 0x00000000, 0x000360C0 },
{ 0x0000002D, 0x00000000, 0x000360C0 },
{ 0x00000030, 0x00000000, 0x00035F42 },
{ 0x00000031, 0x00000000, 0x000360BF },
{ 0x00000032, 0x00000000, 0x000360BF },
{ 0x00000033, 0x00000000, 0x000360C0 },
{ 0x00000034, 0x00000000, 0x00035FC9 },
{ 0x00000035, 0x00000000, 0x00035E8B },
{ 0x00000036, 0x00000000, 0x00035DFA },
{ 0x00000037, 0x00000000, 0x000363AB },
{ 0x00000038, 0x00000000, 0x00035F0F },
{ 0x0000003C, 0x00000000, 0x00036379 },
{ 0x0000003E, 0x00000000, 0x00036262 },
{ 0x0000003F, 0x00000000, 0x00036262 },
{ 0x00000040, 0x00000000, 0x00036271 },
{ 0x00000041, 0x00000000, 0x0003626C },
{ 0x00000042, 0x00000000, 0x0003625D },
{ 0x00000043, 0x00000000, 0x0003649B },
{ 0x00000044, 0x00000000, 0x0003649B },
{ 0x00000046, 0x00000000, 0x00036035 },
{ 0x00000000, 0x00000000, 0x00000000 }
};
static const ScriptQuote LIFTBOT_QUOTES[] = {
{ 0x00033694, 0x00033695, 0x0000001e },
{ 0x00033694, 0x00033695, 0x00000032 },
{ 0x00033694, 0x00033695, 0x00000046 },
{ 0x00033696, 0x00033697, 0x0000003c },
{ 0x00000008, 0x00000000, 0x00033655 },
{ 0x00000007, 0x00000000, 0x000335A0 },
{ 0x00000006, 0x00000000, 0x0003368B },
{ 0x00000005, 0x00000028, 0x00033693 },
{ 0x00000001, 0x56424144, 0x00033695 },
{ 0x00000001, 0x52554445, 0x00033695 },
{ 0x00000001, 0x5052534E, 0x00000003 },
{ 0x00000001, 0x464F4F44, 0x00000003 },
{ 0x00000001, 0x00000032, 0x00000001 },
{ 0x00000002, 0x56424144, 0x00033695 },
{ 0x00000002, 0x52554445, 0x00033695 },
{ 0x00000002, 0x5052534E, 0x00000003 },
{ 0x00000002, 0x464F4F44, 0x00000003 },
{ 0x00000002, 0x00000032, 0x00000001 },
{ 0x00000003, 0x56424144, 0x00033695 },
{ 0x00000003, 0x52554445, 0x00033695 },
{ 0x00000003, 0x5052534E, 0x00000003 },
{ 0x00000003, 0x464F4F44, 0x00000003 },
{ 0x00000003, 0x00000032, 0x00000001 },
{ 0x00000010, 0x54524156, 0x000335A4 },
{ 0x00000010, 0x0000003C, 0x00000000 },
{ 0x00000011, 0x00000000, 0x0003367B },
{ 0x00000015, 0x00000032, 0x000335A1 },
{ 0x00000012, 0x00000042, 0x00033672 },
{ 0x00000013, 0x00000021, 0x00033679 },
{ 0x0000001D, 0x00000021, 0x00033679 },
{ 0x00000014, 0x00000042, 0x00033688 },
{ 0x00000016, 0x0000003C, 0x000335A4 },
{ 0x00000017, 0x00000028, 0x00033689 },
{ 0x00000018, 0x00000000, 0x00033670 },
{ 0x00000019, 0x00000000, 0x000335A0 },
{ 0x0000001A, 0x0000003C, 0x0003368F },
{ 0x0000001B, 0x00000000, 0x00033695 },
{ 0x00000009, 0x00000019, 0x000335A2 },
{ 0x0000000A, 0x00000019, 0x000335A6 },
{ 0x0000000B, 0x00000028, 0x00033668 },
{ 0x0000001E, 0x00000000, 0x00033691 },
{ 0x0000001F, 0x00000000, 0x00033691 },
{ 0x0000000C, 0x00000014, 0x00033666 },
{ 0x0000000D, 0x00000014, 0x00033666 },
{ 0x0000000E, 0x00000014, 0x0003367A },
{ 0x0000000F, 0x00000014, 0x0003367A },
{ 0x00000020, 0x00000019, 0x0003367C },
{ 0x00000021, 0x0000000F, 0x00033690 },
{ 0x00000022, 0x0000000F, 0x00033682 },
{ 0x0000001C, 0x00000032, 0x00000000 },
{ 0x00000023, 0x00000000, 0x00033698 },
{ 0x00000024, 0x00000000, 0x00033699 },
{ 0x00000031, 0x00000000, 0x00033694 },
{ 0x00000032, 0x00000000, 0x00033694 },
{ 0x00000033, 0x00000000, 0x00033695 },
{ 0x00000034, 0x00000000, 0x0003369F },
{ 0x00000035, 0x00000000, 0x000336A0 },
{ 0x00000036, 0x00000000, 0x00033585 },
{ 0x0000003E, 0x00000000, 0x0003380D },
{ 0x0000003F, 0x00000000, 0x0003380D },
{ 0x00000040, 0x00000000, 0x0003380D },
{ 0x00000041, 0x00000000, 0x000337E7 },
{ 0x00000042, 0x00000000, 0x00033711 },
{ 0x00000000, 0x00000000, 0x00000000 }
};
static const ScriptQuote MAITRED_QUOTES[] = {
{ 0x0003f833, 0x0003f847, 0x0000001e },
{ 0x0003f833, 0x0003f847, 0x00000032 },
{ 0x0003f833, 0x0003f847, 0x00000046 },
{ 0x0003f94f, 0x0003f936, 0x0000003c },
{ 0x00000008, 0x00000000, 0x0003F967 },
{ 0x00000007, 0x00000000, 0x0003F995 },
{ 0x00000006, 0x00000000, 0x0003F833 },
{ 0x00000005, 0x00000000, 0x0003F95B },
{ 0x00000001, 0x56424144, 0x0003F847 },
{ 0x00000001, 0x52554445, 0x0003F847 },
{ 0x00000001, 0x5052534E, 0x00041EB3 },
{ 0x00000001, 0x464F4F44, 0x0003FB88 },
{ 0x00000001, 0x00000032, 0x00041EB1 },
{ 0x00000010, 0x54524156, 0x0003F9FA },
{ 0x00000010, 0x0000003C, 0x00041EB0 },
{ 0x00000011, 0x00000000, 0x0003F967 },
{ 0x00000015, 0x00000032, 0x0003F83D },
{ 0x00000012, 0x00000042, 0x0003F83D },
{ 0x00000013, 0x00000021, 0x0003F95B },
{ 0x0000001D, 0x00000021, 0x0003F971 },
{ 0x00000014, 0x00000042, 0x0003F96C },
{ 0x0000001B, 0x00000000, 0x0003F95B },
{ 0x0000001E, 0x00000000, 0x0003FA3C },
{ 0x0000001F, 0x00000000, 0x0003F991 },
{ 0x0000000C, 0x00000000, 0x0003F9C9 },
{ 0x0000000D, 0x00000000, 0x0003F9C9 },
{ 0x0000000E, 0x00000000, 0x0003F9C9 },
{ 0x0000000F, 0x00000000, 0x0003F9C9 },
{ 0x00000020, 0x00000019, 0x0003F847 },
{ 0x00000021, 0x0000000F, 0x0003FA22 },
{ 0x00000037, 0x00000000, 0x0003FA9C },
{ 0x0000003C, 0x00000000, 0x0003FAA0 },
{ 0x00000047, 0x00000000, 0x0003FAA1 },
{ 0x0000003F, 0x00000000, 0x0003FABD },
{ 0x0000003E, 0x00000000, 0x0003FABD },
{ 0x00000040, 0x00000000, 0x0003FABB },
{ 0x00000041, 0x00000000, 0x0003FABB },
{ 0x00000042, 0x00000000, 0x0003FABC },
{ 0x00000048, 0x00000000, 0x0003FB45 },
{ 0x00000049, 0x00000000, 0x0003FB48 },
{ 0x0000004A, 0x00000000, 0x0003FB52 },
{ 0x0000004B, 0x00000000, 0x0003FB4A },
{ 0x0000004C, 0x00000000, 0x0003FB47 },
{ 0x0000004D, 0x00000000, 0x0003FB49 },
{ 0x0000004E, 0x00000000, 0x0003FB53 },
{ 0x0000004F, 0x00000000, 0x0003FB4C },
{ 0x00000050, 0x00000000, 0x0003FB4E },
{ 0x00000051, 0x00000000, 0x0003FB50 },
{ 0x00000052, 0x00000000, 0x0003FB75 },
{ 0x00000053, 0x00000000, 0x0003F9A8 },
{ 0x00000000, 0x00000000, 0x00000000 }
};
void writeScriptQuotes(const char *name, const ScriptQuote *quotes,
uint rangeStart, uint rangeEnd, uint incr) {
outputFile->seek(dataOffset);
outputFile->writeLong(rangeStart);
outputFile->writeLong(rangeEnd);
outputFile->writeLong(incr);
for (; quotes->_index; ++quotes) {
outputFile->writeLong(quotes->_tag1);
outputFile->writeLong(quotes->_tag2);
outputFile->writeLong(quotes->_index);
}
uint size = outputFile->size() - dataOffset;
writeEntryHeader(name, dataOffset, size);
dataOffset += size;
}
void writeAllScriptQuotes() {
writeScriptQuotes("Quotes/Barbot", BARBOT_QUOTES, 0, 999, 90);
writeScriptQuotes("Quotes/Bellbot", BELLBOT_QUOTES, 270000, 270500, 25);
writeScriptQuotes("Quotes/Deskbot", DESKBOT_QUOTES, 270000, 270500, 25);
writeScriptQuotes("Quotes/Doorbot", DOORBOT_QUOTES, 0, 999, 25);
writeScriptQuotes("Quotes/Liftbot", LIFTBOT_QUOTES, 0, 999, 57);
writeScriptQuotes("Quotes/MaitreD", MAITRED_QUOTES, 270000, 270500, 25);
}

View File

@@ -0,0 +1,36 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COMMON_SCRIPT_QUOTES_H
#define COMMON_SCRIPT_QUOTES_H
#include "common/scummsys.h"
struct ScriptQuote {
uint _tag1;
uint _tag2;
uint _index;
};
extern void writeAllScriptQuotes();
extern uint dataOffset;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COMMON_SCRIPT_RANGES_H
#define COMMON_SCRIPT_RANGES_H
#include "common/scummsys.h"
struct ScriptRange {
uint _id;
const uint *_array;
bool _isRandom;
bool _isSequential;
};
extern void writeAllScriptRanges();
extern uint dataOffset;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COMMON_SCRIPT_TAGS_H
#define COMMON_SCRIPT_TAGS_H
#include "common/scummsys.h"
extern void writeAllScriptResponses();
extern uint dataOffset;
#endif

View File

@@ -0,0 +1,543 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "file.h"
#include "script_states.h"
extern void writeEntryHeader(const char *name, uint offset, uint size);
static const UpdateState12 BARBOT_STATES[] = {
{ 0x0003AB24, 0x00000005, 0x00 },
{ 0x0003AD33, 0x00000005, 0x00 },
{ 0x0003AB40, 0x00000008, 0x00 },
{ 0x0003AC6A, 0x00000008, 0x00 },
{ 0x0003AB3E, 0x00000006, 0x00 },
{ 0x0003AB3D, 0x00000006, 0x00 },
{ 0x0003AB41, 0x00000007, 0x00 },
{ 0x0003AB69, 0x00000008, 0x00 },
{ 0x0003AE6D, 0x0000004E, 0x00 },
{ 0x0003AC69, 0x0000004E, 0x00 },
{ 0x0003AE6E, 0x0000004F, 0x00 },
{ 0x0003AE6F, 0x00000051, 0x00 },
{ 0x0003AE70, 0x00000051, 0x00 },
{ 0x0003AE71, 0x00000051, 0x00 },
{ 0x0003AE72, 0x00000051, 0x00 },
{ 0x0003AE73, 0x00000051, 0x00 },
{ 0x0003AE74, 0x00000051, 0x00 },
{ 0x0003AE75, 0x00000051, 0x00 },
{ 0x0003AE76, 0x00000051, 0x00 },
{ 0x0003AE77, 0x00000051, 0x00 },
{ 0x0003AEB8, 0x00000051, 0x00 },
{ 0x0003AB20, 0x00000009, 0x00 },
{ 0x0003AB14, 0x0000000A, 0x00 },
{ 0x0003AB15, 0x0000000B, 0x00 },
{ 0x0003AB16, 0x0000000C, 0x00 },
{ 0x0003AB63, 0x0000000D, 0x00 },
{ 0x0003AB64, 0x0000000D, 0x00 },
{ 0x0003AB44, 0x00000001, 0x00 },
{ 0x0003AB43, 0x00000001, 0x0B },
{ 0x0003AB2A, 0x00000002, 0x00 },
{ 0x0003AB4A, 0x00000003, 0x0B },
{ 0x0003AB4C, 0x00000003, 0x0B },
{ 0x0003AB65, 0x00000004, 0x00 },
{ 0x0003AB2F, 0x0000000E, 0x00 },
{ 0x0003AB30, 0x0000000F, 0x00 },
{ 0x0003AB17, 0x00000010, 0x0B },
{ 0x0003AB18, 0x00000010, 0x0B },
{ 0x0003AAE3, 0x0000003E, 0x00 },
{ 0x0003AAE4, 0x0000003E, 0x00 },
{ 0x0003AAE5, 0x0000003E, 0x00 },
{ 0x0003AB0F, 0x00000011, 0x00 },
{ 0x0003AB11, 0x00000012, 0x00 },
{ 0x0003AB12, 0x00000013, 0x00 },
{ 0x0003AB13, 0x00000014, 0x00 },
{ 0x0003AADC, 0x00000019, 0x00 },
{ 0x0003AADD, 0x0000001A, 0x00 },
{ 0x0003AADE, 0x0000001B, 0x00 },
{ 0x0003AAFD, 0x00000015, 0x00 },
{ 0x0003AAFE, 0x00000016, 0x00 },
{ 0x0003AAFF, 0x00000017, 0x00 },
{ 0x0003AB00, 0x00000018, 0x00 },
{ 0x0003AAF4, 0x0000001C, 0x00 },
{ 0x0003AAF5, 0x0000001D, 0x00 },
{ 0x0003AAF6, 0x0000001E, 0x00 },
{ 0x0003AAD9, 0x0000001F, 0x00 },
{ 0x0003AADA, 0x00000020, 0x00 },
{ 0x0003AADB, 0x00000021, 0x00 },
{ 0x0003AAF7, 0x00000022, 0x00 },
{ 0x0003AAF8, 0x00000023, 0x00 },
{ 0x0003AAF9, 0x00000024, 0x00 },
{ 0x0003AB04, 0x0000002C, 0x00 },
{ 0x0003AB05, 0x0000002D, 0x00 },
{ 0x0003AB06, 0x0000002E, 0x00 },
{ 0x0003AADF, 0x00000029, 0x00 },
{ 0x0003AAE0, 0x0000002A, 0x00 },
{ 0x0003AAE1, 0x0000002B, 0x00 },
{ 0x0003AB07, 0x00000038, 0x00 },
{ 0x0003AB08, 0x00000039, 0x00 },
{ 0x0003AB09, 0x0000003A, 0x00 },
{ 0x0003AB01, 0x0000003B, 0x00 },
{ 0x0003AB02, 0x0000003C, 0x00 },
{ 0x0003AB03, 0x0000003D, 0x00 },
{ 0x0003AAF0, 0x00000025, 0x00 },
{ 0x0003AAF1, 0x00000026, 0x00 },
{ 0x0003AAF2, 0x00000027, 0x00 },
{ 0x0003AAF3, 0x00000028, 0x00 },
{ 0x0003AB0A, 0x0000002F, 0x00 },
{ 0x0003AB0B, 0x00000030, 0x00 },
{ 0x0003AB0C, 0x00000031, 0x00 },
{ 0x0003AB0D, 0x00000032, 0x00 },
{ 0x0003AAEA, 0x00000033, 0x00 },
{ 0x0003AAEB, 0x00000034, 0x00 },
{ 0x0003AAEC, 0x00000035, 0x00 },
{ 0x0003AAED, 0x00000036, 0x00 },
{ 0x0003AAEE, 0x00000037, 0x00 },
{ 0x0003ACC3, 0x0000003F, 0x00 },
{ 0x0003ACC4, 0x00000040, 0x00 },
{ 0x0003ACC5, 0x00000041, 0x00 },
{ 0x0003ACC6, 0x00000042, 0x00 },
{ 0x0003ACC7, 0x00000043, 0x00 },
{ 0x0003ACC8, 0x00000044, 0x00 },
{ 0x0003ADCF, 0x00000045, 0x00 },
{ 0x0003ADD0, 0x00000046, 0x00 },
{ 0x0003ADD1, 0x00000047, 0x00 },
{ 0x0003ADD2, 0x00000048, 0x00 },
{ 0x0003ADD3, 0x00000049, 0x00 },
{ 0x0003ACA4, 0x0000004A, 0x00 },
{ 0x0003ACA7, 0x0000004B, 0x00 },
{ 0x0003ADD5, 0x0000004C, 0x00 },
{ 0x0003AC7E, 0x0000004C, 0x00 },
{ 0x0003ABF9, 0x0000004C, 0x00 },
{ 0x0003AD14, 0x0000004C, 0x00 },
{ 0x0003AD15, 0x0000004C, 0x00 },
{ 0x0003AD10, 0x0000004C, 0x00 },
{ 0x0003AD17, 0x0000004C, 0x00 },
{ 0x0003AD21, 0x0000004C, 0x00 },
{ 0x0003AD2F, 0x0000004C, 0x00 },
{ 0x0003AC7F, 0x0000004D, 0x00 },
{ 0x0003AEBA, 0x00000052, 0x0E },
{ 0x0003AED5, 0x00000053, 0x00 },
{ 0x0003B034, 0x00000054, 0x00 },
{ 0x0003B037, 0x00000054, 0x00 },
{ 0x0003B036, 0x00000055, 0x00 },
{ 0x0003B035, 0x00000055, 0x00 },
{ 0x0003B02D, 0x00000055, 0x00 },
{ 0x0003B02F, 0x00000055, 0x00 },
{ 0x0003B02E, 0x00000056, 0x00 },
{ 0x0003B031, 0x00000056, 0x00 },
{ 0x0003B033, 0x00000056, 0x00 },
{ 0x0003B032, 0x00000057, 0x00 },
{ 0x0003B023, 0x00000057, 0x00 },
{ 0x0003B025, 0x00000057, 0x00 },
{ 0x0003B024, 0x00000058, 0x00 },
{ 0x0003B017, 0x00000058, 0x00 },
{ 0x0003B01C, 0x00000058, 0x00 },
{ 0x0003B01A, 0x00000059, 0x00 },
{ 0x0003B01B, 0x0000005A, 0x00 },
{ 0x0003B018, 0x0000005B, 0x00 },
{ 0x0003B019, 0x0000005D, 0x00 },
{ 0x0003B01D, 0x0000005D, 0x00 },
{ 0x0003B01E, 0x0000005D, 0x00 },
{ 0x0003B01F, 0x0000005D, 0x00 },
{ 0x0003B026, 0x0000005D, 0x00 },
{ 0x0003B027, 0x0000005D, 0x00 },
{ 0x0003B028, 0x0000005D, 0x00 },
{ 0x0003B029, 0x0000005D, 0x00 },
{ 0x0003B030, 0x0000005D, 0x00 },
{ 0x0003B02A, 0x0000005E, 0x00 },
{ 0x0003ABF7, 0x0000005F, 0x00 },
{ 0x0003AF6A, 0x00000060, 0x00 },
{ 0x0003AEC6, 0x00000061, 0x00 },
{ 0x00000000, 0x00000000, 0x00 }
};
static const UpdateState8 BELLBOT_STATES[] = {
{ 0x00031070, 0x00000001 }, { 0x0003107B, 0x00000002 }, { 0x0003107E, 0x00000003 },
{ 0x0003104F, 0x00000004 }, { 0x00030F23, 0x00000005 }, { 0x00030F2A, 0x00000006 },
{ 0x00030F31, 0x00000007 }, { 0x00030F32, 0x00000007 }, { 0x00030F33, 0x00000007 },
{ 0x00030F34, 0x00000007 }, { 0x00030F35, 0x00000007 }, { 0x00030F36, 0x00000007 },
{ 0x00030F37, 0x00000008 }, { 0x00030F2E, 0x00000009 }, { 0x00030E78, 0x0000000A },
{ 0x00030E42, 0x0000000C }, { 0x00030E0C, 0x0000000D }, { 0x00030E9C, 0x0000000E },
{ 0x00030DC1, 0x0000000F }, { 0x00030DC2, 0x00000010 }, { 0x00030D6B, 0x00000011 },
{ 0x00030D6C, 0x00000011 }, { 0x00030E1D, 0x00000012 }, { 0x00030E1E, 0x00000013 },
{ 0x00030E3B, 0x00000014 }, { 0x00030EBA, 0x00000015 }, { 0x00031086, 0x00000016 },
{ 0x000310A4, 0x00000017 }, { 0x00031058, 0x00000018 }, { 0x00031059, 0x00000019 },
{ 0x00030E3F, 0x0000001A }, { 0x00030EBC, 0x0000001B }, { 0x00030E9B, 0x0000001C },
{ 0x00030E32, 0x0000001D }, { 0x00030E76, 0x0000001E }, { 0x00031060, 0x0000001F },
{ 0x00031065, 0x00000020 }, { 0x00031075, 0x00000021 }, { 0x00031077, 0x00000022 },
{ 0x00031041, 0x00000023 }, { 0x00031038, 0x00000024 }, { 0x00030FAB, 0x00000025 },
{ 0x00030FAF, 0x00000026 }, { 0x00030FB1, 0x00000027 }, { 0x00030FB8, 0x00000028 },
{ 0x00030FB2, 0x00000029 }, { 0x00030FC1, 0x0000002A }, { 0x00030FC2, 0x0000002B },
{ 0x00030FA4, 0x0000002C }, { 0x00030FA5, 0x0000002D }, { 0x00030FA7, 0x0000002E },
{ 0x00030FA8, 0x0000002C }, { 0x00030FA6, 0x0000002C }, { 0x00030EAD, 0x0000002F },
{ 0x00030EAE, 0x00000030 }, { 0x00030ED6, 0x00000031 }, { 0x00030ED7, 0x00000032 },
{ 0x00030ED8, 0x00000033 }, { 0x000310A9, 0x00000034 }, { 0x00030F4C, 0x00000035 },
{ 0x00030DA7, 0x00000036 }, { 0x00030D9F, 0x00000037 }, { 0x00030FC8, 0x00000038 },
{ 0x00030FC9, 0x00000039 }, { 0x00030FCF, 0x0000003A }, { 0x00030FCA, 0x0000003B },
{ 0x00030FCB, 0x0000003C }, { 0x00030FCC, 0x0000003D }, { 0x00030E41, 0x0000003E },
{ 0x00030E12, 0x0000003F }, { 0x00030D72, 0x00000040 }, { 0x00030D76, 0x00000041 },
{ 0x00030D78, 0x00000042 }, { 0x00030D79, 0x00000043 }, { 0x000310AE, 0x00000044 },
{ 0x0003112C, 0x00000044 }, { 0x00031132, 0x00000045 }, { 0x00031133, 0x00000046 },
{ 0x00031134, 0x00000047 }, { 0x000310D7, 0x00000048 }, { 0x0003113C, 0x00000049 },
{ 0x0003113E, 0x0000004A }, { 0x0003113D, 0x0000004A }, { 0x00031146, 0x0000004B },
{ 0x00031149, 0x0000004C }, { 0x0003114A, 0x0000004D }, { 0x0003114E, 0x0000004E },
{ 0x00031151, 0x0000004E }, { 0x0003114F, 0x0000004E }, { 0x00031152, 0x0000004E },
{ 0x0003115B, 0x0000004F }, { 0x00031163, 0x00000050 }, { 0x00031164, 0x00000051 },
{ 0x00031165, 0x00000051 }, { 0x00031166, 0x00000051 }, { 0x00031167, 0x00000052 },
{ 0x0003117A, 0x00000053 }, { 0x0003149A, 0x00000054 }, { 0x00031454, 0x00000055 },
{ 0x0003157B, 0x00000056 }, { 0x00031177, 0x00000057 }, { 0x00031171, 0x00000057 },
{ 0x0003117A, 0x00000057 }, { 0x00031507, 0x00000057 }, { 0x0003159D, 0x00000058 },
{ 0x000315DD, 0x00000059 }, { 0x00031147, 0x0000005A }, { 0x00031148, 0x0000005A },
{ 0x00000000, 0x00000000 }
};
static const UpdateState12 DESKBOT_STATES[] = {
{ 0x0003AB24, 0x00000005, 0x00 },
{ 0x0003AD33, 0x00000005, 0x00 },
{ 0x0003AB40, 0x00000008, 0x00 },
{ 0x0003AC6A, 0x00000008, 0x00 },
{ 0x0003AB3E, 0x00000006, 0x00 },
{ 0x0003AB3D, 0x00000006, 0x00 },
{ 0x0003AB41, 0x00000007, 0x00 },
{ 0x0003AB69, 0x00000008, 0x00 },
{ 0x0003AE6D, 0x0000004E, 0x00 },
{ 0x0003AC69, 0x0000004E, 0x00 },
{ 0x0003AE6E, 0x0000004F, 0x00 },
{ 0x0003AE6F, 0x00000051, 0x00 },
{ 0x0003AE70, 0x00000051, 0x00 },
{ 0x0003AE71, 0x00000051, 0x00 },
{ 0x0003AE72, 0x00000051, 0x00 },
{ 0x0003AE73, 0x00000051, 0x00 },
{ 0x0003AE74, 0x00000051, 0x00 },
{ 0x0003AE75, 0x00000051, 0x00 },
{ 0x0003AE76, 0x00000051, 0x00 },
{ 0x0003AE77, 0x00000051, 0x00 },
{ 0x0003AEB8, 0x00000051, 0x00 },
{ 0x0003AB20, 0x00000009, 0x00 },
{ 0x0003AB14, 0x0000000A, 0x00 },
{ 0x0003AB15, 0x0000000B, 0x00 },
{ 0x0003AB16, 0x0000000C, 0x00 },
{ 0x0003AB63, 0x0000000D, 0x00 },
{ 0x0003AB64, 0x0000000D, 0x00 },
{ 0x0003AB44, 0x00000001, 0x00 },
{ 0x0003AB43, 0x00000001, 0x0B },
{ 0x0003AB2A, 0x00000002, 0x00 },
{ 0x0003AB4A, 0x00000003, 0x0B },
{ 0x0003AB4C, 0x00000003, 0x0B },
{ 0x0003AB65, 0x00000004, 0x00 },
{ 0x0003AB2F, 0x0000000E, 0x00 },
{ 0x0003AB30, 0x0000000F, 0x00 },
{ 0x0003AB17, 0x00000010, 0x0B },
{ 0x0003AB18, 0x00000010, 0x0B },
{ 0x0003AAE3, 0x0000003E, 0x00 },
{ 0x0003AAE4, 0x0000003E, 0x00 },
{ 0x0003AAE5, 0x0000003E, 0x00 },
{ 0x0003AB0F, 0x00000011, 0x00 },
{ 0x0003AB11, 0x00000012, 0x00 },
{ 0x0003AB12, 0x00000013, 0x00 },
{ 0x0003AB13, 0x00000014, 0x00 },
{ 0x0003AADC, 0x00000019, 0x00 },
{ 0x0003AADD, 0x0000001A, 0x00 },
{ 0x0003AADE, 0x0000001B, 0x00 },
{ 0x0003AAFD, 0x00000015, 0x00 },
{ 0x0003AAFE, 0x00000016, 0x00 },
{ 0x0003AAFF, 0x00000017, 0x00 },
{ 0x0003AB00, 0x00000018, 0x00 },
{ 0x0003AAF4, 0x0000001C, 0x00 },
{ 0x0003AAF5, 0x0000001D, 0x00 },
{ 0x0003AAF6, 0x0000001E, 0x00 },
{ 0x0003AAD9, 0x0000001F, 0x00 },
{ 0x0003AADA, 0x00000020, 0x00 },
{ 0x0003AADB, 0x00000021, 0x00 },
{ 0x0003AAF7, 0x00000022, 0x00 },
{ 0x0003AAF8, 0x00000023, 0x00 },
{ 0x0003AAF9, 0x00000024, 0x00 },
{ 0x0003AB04, 0x0000002C, 0x00 },
{ 0x0003AB05, 0x0000002D, 0x00 },
{ 0x0003AB06, 0x0000002E, 0x00 },
{ 0x0003AADF, 0x00000029, 0x00 },
{ 0x0003AAE0, 0x0000002A, 0x00 },
{ 0x0003AAE1, 0x0000002B, 0x00 },
{ 0x0003AB07, 0x00000038, 0x00 },
{ 0x0003AB08, 0x00000039, 0x00 },
{ 0x0003AB09, 0x0000003A, 0x00 },
{ 0x0003AB01, 0x0000003B, 0x00 },
{ 0x0003AB02, 0x0000003C, 0x00 },
{ 0x0003AB03, 0x0000003D, 0x00 },
{ 0x0003AAF0, 0x00000025, 0x00 },
{ 0x0003AAF1, 0x00000026, 0x00 },
{ 0x0003AAF2, 0x00000027, 0x00 },
{ 0x0003AAF3, 0x00000028, 0x00 },
{ 0x0003AB0A, 0x0000002F, 0x00 },
{ 0x0003AB0B, 0x00000030, 0x00 },
{ 0x0003AB0C, 0x00000031, 0x00 },
{ 0x0003AB0D, 0x00000032, 0x00 },
{ 0x0003AAEA, 0x00000033, 0x00 },
{ 0x0003AAEB, 0x00000034, 0x00 },
{ 0x0003AAEC, 0x00000035, 0x00 },
{ 0x0003AAED, 0x00000036, 0x00 },
{ 0x0003AAEE, 0x00000037, 0x00 },
{ 0x0003ACC3, 0x0000003F, 0x00 },
{ 0x0003ACC4, 0x00000040, 0x00 },
{ 0x0003ACC5, 0x00000041, 0x00 },
{ 0x0003ACC6, 0x00000042, 0x00 },
{ 0x0003ACC7, 0x00000043, 0x00 },
{ 0x0003ACC8, 0x00000044, 0x00 },
{ 0x0003ADCF, 0x00000045, 0x00 },
{ 0x0003ADD0, 0x00000046, 0x00 },
{ 0x0003ADD1, 0x00000047, 0x00 },
{ 0x0003ADD2, 0x00000048, 0x00 },
{ 0x0003ADD3, 0x00000049, 0x00 },
{ 0x0003ACA4, 0x0000004A, 0x00 },
{ 0x0003ACA7, 0x0000004B, 0x00 },
{ 0x0003ADD5, 0x0000004C, 0x00 },
{ 0x0003AC7E, 0x0000004C, 0x00 },
{ 0x0003ABF9, 0x0000004C, 0x00 },
{ 0x0003AD14, 0x0000004C, 0x00 },
{ 0x0003AD15, 0x0000004C, 0x00 },
{ 0x0003AD10, 0x0000004C, 0x00 },
{ 0x0003AD17, 0x0000004C, 0x00 },
{ 0x0003AD21, 0x0000004C, 0x00 },
{ 0x0003AD2F, 0x0000004C, 0x00 },
{ 0x0003AC7F, 0x0000004D, 0x00 },
{ 0x0003AEBA, 0x00000052, 0x0E },
{ 0x0003AED5, 0x00000053, 0x00 },
{ 0x0003B034, 0x00000054, 0x00 },
{ 0x0003B037, 0x00000054, 0x00 },
{ 0x0003B036, 0x00000055, 0x00 },
{ 0x0003B035, 0x00000055, 0x00 },
{ 0x0003B02D, 0x00000055, 0x00 },
{ 0x0003B02F, 0x00000055, 0x00 },
{ 0x0003B02E, 0x00000056, 0x00 },
{ 0x0003B031, 0x00000056, 0x00 },
{ 0x0003B033, 0x00000056, 0x00 },
{ 0x0003B032, 0x00000057, 0x00 },
{ 0x0003B023, 0x00000057, 0x00 },
{ 0x0003B025, 0x00000057, 0x00 },
{ 0x0003B024, 0x00000058, 0x00 },
{ 0x0003B017, 0x00000058, 0x00 },
{ 0x0003B01C, 0x00000058, 0x00 },
{ 0x0003B01A, 0x00000059, 0x00 },
{ 0x0003B01B, 0x0000005A, 0x00 },
{ 0x0003B018, 0x0000005B, 0x00 },
{ 0x0003B019, 0x0000005D, 0x00 },
{ 0x0003B01D, 0x0000005D, 0x00 },
{ 0x0003B01E, 0x0000005D, 0x00 },
{ 0x0003B01F, 0x0000005D, 0x00 },
{ 0x0003B026, 0x0000005D, 0x00 },
{ 0x0003B027, 0x0000005D, 0x00 },
{ 0x0003B028, 0x0000005D, 0x00 },
{ 0x0003B029, 0x0000005D, 0x00 },
{ 0x0003B030, 0x0000005D, 0x00 },
{ 0x0003B02A, 0x0000005E, 0x00 },
{ 0x0003ABF7, 0x0000005F, 0x00 },
{ 0x0003AF6A, 0x00000060, 0x00 },
{ 0x0003AEC6, 0x00000061, 0x00 },
{ 0x00000000, 0x00000000, 0x00 }
};
static const UpdateState12 DOORBOT_STATES[] = {
{ 0x00035BD0, 0x00000004, 0x06 },
{ 0x00035BE7, 0x00000005, 0x00 },
{ 0x00035BED, 0x00000006, 0x0A },
{ 0x00035E41, 0x0000000C, 0x0A },
{ 0x00035F9D, 0x0000000F, 0x00 },
{ 0x00035F81, 0x00000010, 0x00 },
{ 0x00035F82, 0x00000010, 0x00 },
{ 0x00035F83, 0x00000010, 0x00 },
{ 0x00035F84, 0x00000010, 0x00 },
{ 0x00035F85, 0x00000010, 0x00 },
{ 0x00035FC5, 0x00000011, 0x00 },
{ 0x00035B6C, 0x00000021, 0x02 },
{ 0x00035B6D, 0x00000022, 0x02 },
{ 0x00035FCD, 0x00000012, 0x00 },
{ 0x00035EF0, 0x00000020, 0x00 },
{ 0x00035EF1, 0x00000020, 0x00 },
{ 0x00035F0A, 0x00000020, 0x00 },
{ 0x000362B0, 0x00000013, 0x00 },
{ 0x000362B1, 0x00000013, 0x00 },
{ 0x000362B2, 0x00000013, 0x00 },
{ 0x000362B3, 0x00000013, 0x00 },
{ 0x000362B4, 0x00000013, 0x00 },
{ 0x000362B5, 0x00000013, 0x00 },
{ 0x000362B9, 0x00000013, 0x00 },
{ 0x000362BB, 0x00000013, 0x00 },
{ 0x000362BA, 0x00000013, 0x00 },
{ 0x000362BC, 0x00000013, 0x00 },
{ 0x000362B8, 0x00000013, 0x00 },
{ 0x000362BD, 0x00000013, 0x00 },
{ 0x000362BE, 0x00000013, 0x00 },
{ 0x000362BF, 0x00000013, 0x00 },
{ 0x000362C0, 0x00000013, 0x00 },
{ 0x000362C1, 0x00000013, 0x00 },
{ 0x000362C2, 0x00000013, 0x00 },
{ 0x000362B6, 0x00000014, 0x00 },
{ 0x00035F8A, 0x00000015, 0x00 },
{ 0x00036407, 0x00000016, 0x00 },
{ 0x0003640C, 0x00000016, 0x00 },
{ 0x0003641A, 0x00000016, 0x00 },
{ 0x00036420, 0x00000016, 0x00 },
{ 0x00036421, 0x00000016, 0x00 },
{ 0x00036422, 0x00000016, 0x00 },
{ 0x00036408, 0x00000016, 0x00 },
{ 0x0003640A, 0x00000016, 0x00 },
{ 0x0003640B, 0x00000016, 0x00 },
{ 0x0003640D, 0x00000018, 0x00 },
{ 0x00036415, 0x00000016, 0x00 },
{ 0x00036416, 0x00000016, 0x00 },
{ 0x00036417, 0x00000016, 0x00 },
{ 0x00036418, 0x00000016, 0x00 },
{ 0x00036419, 0x00000016, 0x00 },
{ 0x0003640E, 0x00000016, 0x00 },
{ 0x0003640F, 0x00000016, 0x00 },
{ 0x00036410, 0x00000016, 0x00 },
{ 0x00036411, 0x00000019, 0x00 },
{ 0x00036412, 0x0000001A, 0x00 },
{ 0x0003641B, 0x00000016, 0x00 },
{ 0x0003641C, 0x00000016, 0x00 },
{ 0x0003641D, 0x00000016, 0x00 },
{ 0x0003641F, 0x00000016, 0x00 },
{ 0x00035FF6, 0x0000001B, 0x00 },
{ 0x00035FF7, 0x0000001C, 0x00 },
{ 0x00035FF8, 0x0000001D, 0x00 },
{ 0x00035FF9, 0x0000001E, 0x00 },
{ 0x0003627F, 0x00000023, 0x00 },
{ 0x00036280, 0x00000024, 0x00 },
{ 0x00036281, 0x00000025, 0x00 },
{ 0x00036282, 0x00000025, 0x00 },
{ 0x00036457, 0x00000026, 0x00 },
{ 0x00000000, 0x00000000, 0x00 }
};
static const UpdateState8 LIFTBOT_STATES[] = {
{ 0x000335D6, 0x00000004 },
{ 0x000337A7, 0x00000005 },
{ 0x00033781, 0x00000006 },
{ 0x0003381A, 0x00000009 },
{ 0x0003381B, 0x00000009 },
{ 0x0003381E, 0x00000009 },
{ 0x0003381F, 0x00000009 },
{ 0x00033820, 0x00000009 },
{ 0x00033821, 0x00000009 },
{ 0x00033822, 0x00000009 },
{ 0x00033823, 0x00000009 },
{ 0x00033824, 0x00000009 },
{ 0x00033825, 0x00000009 },
{ 0x0003381C, 0x00000009 },
{ 0x0003381D, 0x00000009 },
{ 0x00000000, 0x00000000 }
};
static const UpdateState8 MAITRED_STATES[] = {
{ 0x0003F7D4, 0x00000002 },
{ 0x0003F808, 0x00000003 },
{ 0x0003F809, 0x00000009 },
{ 0x0003F7F9, 0x00000009 },
{ 0x0003F7D2, 0x00000009 },
{ 0x0003F7F6, 0x00000004 },
{ 0x0003F7D3, 0x00000005 },
{ 0x0003F800, 0x00000006 },
{ 0x0003F801, 0x00000007 },
{ 0x0003F7FC, 0x00000008 },
{ 0x0003F7FD, 0x00000008 },
{ 0x0003F7F8, 0x00000008 },
{ 0x0003F7FA, 0x00000008 },
{ 0x0003F7F1, 0x0000000A },
{ 0x0003F7F2, 0x0000000A },
{ 0x0003F7F3, 0x0000000A },
{ 0x0003F7F4, 0x0000000A },
{ 0x0003F7F5, 0x0000000A },
{ 0x0003F877, 0x0000000B },
{ 0x0003FA55, 0x0000000C },
{ 0x0003F863, 0x0000000C },
{ 0x0003F864, 0x0000000C },
{ 0x0003F865, 0x0000000C },
{ 0x0003F866, 0x0000000D },
{ 0x0003F867, 0x0000000E },
{ 0x0003F86E, 0x0000000E },
{ 0x0003F868, 0x0000000F },
{ 0x0003F869, 0x0000000C },
{ 0x0003F870, 0x00000010 },
{ 0x0003F87C, 0x00000011 },
{ 0x0003F87D, 0x00000011 },
{ 0x0003F886, 0x00000012 },
{ 0x0003F889, 0x00000013 },
{ 0x0003F88A, 0x00000014 },
{ 0x0003F88B, 0x00000015 },
{ 0x0003F88C, 0x00000015 },
{ 0x0003F88D, 0x00000016 },
{ 0x0003F88E, 0x00000016 },
{ 0x0003F895, 0x00000016 },
{ 0x0003F893, 0x00000017 },
{ 0x0003F89A, 0x00000018 },
{ 0x0003F875, 0x00000019 },
{ 0x0003F89C, 0x00000019 },
{ 0x0003F8A3, 0x00000019 },
{ 0x0003F8A2, 0x00000019 },
{ 0x0003F89D, 0x0000001A },
{ 0x0003F89E, 0x0000001A },
{ 0x0003F89F, 0x0000001A },
{ 0x0003F8A5, 0x0000001B },
{ 0x0003F921, 0x0000001C },
{ 0x0003F922, 0x0000001C },
{ 0x0003FA56, 0x0000001E },
{ 0x00000000, 0x00000000 }
};
void writeUpdateStates(const char *name, const UpdateState8 *states) {
outputFile->seek(dataOffset);
for (; states->_src; ++states) {
outputFile->writeLong(states->_src);
outputFile->writeLong(states->_dest);
}
uint size = outputFile->size() - dataOffset;
writeEntryHeader(name, dataOffset, size);
dataOffset += size;
}
void writeUpdateStates(const char *name, const UpdateState12 *states) {
outputFile->seek(dataOffset);
for (; states->_newId; ++states) {
outputFile->writeLong(states->_newId);
outputFile->writeLong(states->_newValue);
outputFile->writeLong(states->_idMatch);
}
uint size = outputFile->size() - dataOffset;
writeEntryHeader(name, dataOffset, size);
dataOffset += size;
}
void writeAllUpdateStates() {
writeUpdateStates("States/Barbot", BARBOT_STATES);
writeUpdateStates("States/Bellbot", BELLBOT_STATES);
writeUpdateStates("States/Deskbot", DESKBOT_STATES);
writeUpdateStates("States/Doorbot", DOORBOT_STATES);
writeUpdateStates("States/Liftbot", LIFTBOT_STATES);
writeUpdateStates("States/MaitreD", MAITRED_STATES);
}

View File

@@ -0,0 +1,41 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COMMON_SCRIPT_STATES_H
#define COMMON_SCRIPT_STATES_H
#include "common/scummsys.h"
struct UpdateState12 {
uint _newId;
uint _newValue;
uint _idMatch;
};
struct UpdateState8 {
uint _src;
uint _dest;
};
extern void writeAllUpdateStates();
extern uint dataOffset;
#endif

View File

@@ -0,0 +1,2 @@
#define SCUMMVM_UTIL
#include "../common/str.cpp"

View File

@@ -0,0 +1,716 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "file.h"
#include "tag_maps.h"
#define BARBOT_COUNT_EN 250
static const TagMapping BARBOT_MAP_EN[250] = {
{ 0x46cd0, 0x3d21e }, { 0x46ce2, 0x3d23b }, { 0x46ced, 0x3d246 },
{ 0x46cf8, 0x3d251 }, { 0x46d03, 0x3d25c }, { 0x46d0e, 0x3d267 },
{ 0x46d19, 0x3d272 }, { 0x46d24, 0x3d27d }, { 0x46d2f, 0x3d288 },
{ 0x46cd1, 0x3d21f }, { 0x46cd9, 0x3d22a }, { 0x46cda, 0x3d233 },
{ 0x46cdb, 0x3d234 }, { 0x46cdc, 0x3d235 }, { 0x46cdd, 0x3d236 },
{ 0x46cde, 0x3d237 }, { 0x46cdf, 0x3d238 }, { 0x46ce0, 0x3d239 },
{ 0x46ce1, 0x3d23a }, { 0x46ce3, 0x3d23c }, { 0x46ce4, 0x3d23d },
{ 0x46ce5, 0x3d23e }, { 0x46ce6, 0x3d23f }, { 0x46ce7, 0x3d240 },
{ 0x46ce8, 0x3d241 }, { 0x46ce9, 0x3d242 }, { 0x46cea, 0x3d243 },
{ 0x46ceb, 0x3d244 }, { 0x46cec, 0x3d245 }, { 0x46cee, 0x3d26b },
{ 0x46cef, 0x3d247 }, { 0x46cf0, 0x3d248 }, { 0x46cf1, 0x3d249 },
{ 0x46cf2, 0x3d24a }, { 0x46cf3, 0x3d24b }, { 0x46cf4, 0x3d24c },
{ 0x46cf5, 0x3d24d }, { 0x46cf6, 0x3d24e }, { 0x46cf7, 0x3d24f },
{ 0x46cf9, 0x3d250 }, { 0x46cfa, 0x3d252 }, { 0x46cfb, 0x3d253 },
{ 0x46cfc, 0x3d254 }, { 0x46cfd, 0x3d255 }, { 0x46cfe, 0x3d256 },
{ 0x46cff, 0x3d257 }, { 0x46d00, 0x3d258 }, { 0x46d01, 0x3d259 },
{ 0x46d02, 0x3d25a }, { 0x46d04, 0x3d25b }, { 0x46d05, 0x3d25d },
{ 0x46d06, 0x3d25e }, { 0x46d07, 0x3d25f }, { 0x46d08, 0x3d260 },
{ 0x46d09, 0x3d26f }, { 0x46d0a, 0x3d270 }, { 0x46d0b, 0x3d271 },
{ 0x46d0c, 0x3d273 }, { 0x46d0d, 0x3d274 }, { 0x46d0f, 0x3d275 },
{ 0x46d10, 0x3d276 }, { 0x46d11, 0x3d277 }, { 0x46d12, 0x3d278 },
{ 0x46d13, 0x3d279 }, { 0x46d14, 0x3d27a }, { 0x46d15, 0x3d27b },
{ 0x46d16, 0x3d27c }, { 0x46d17, 0x3d27e }, { 0x46d18, 0x3d27f },
{ 0x46d1a, 0x3d280 }, { 0x46d1b, 0x3d281 }, { 0x46d1c, 0x3d282 },
{ 0x46d1d, 0x3d283 }, { 0x46d1e, 0x3d284 }, { 0x46d1f, 0x3d285 },
{ 0x46d20, 0x3d286 }, { 0x46d21, 0x3d287 }, { 0x46d22, 0x3d289 },
{ 0x46d23, 0x3d28a }, { 0x46d25, 0x3d28b }, { 0x46d26, 0x3d28c },
{ 0x46d27, 0x3d28d }, { 0x46d28, 0x3d28e }, { 0x46d29, 0x3d28f },
{ 0x46d2a, 0x3d290 }, { 0x46d2b, 0x3d291 }, { 0x46d2c, 0x3d292 },
{ 0x46d2d, 0x3d220 }, { 0x46d2e, 0x3d221 }, { 0x46d30, 0x3d222 },
{ 0x46d31, 0x3d223 }, { 0x46d32, 0x3d224 }, { 0x46d33, 0x3d225 },
{ 0x46d34, 0x3d226 }, { 0x46d35, 0x3d227 }, { 0x46d36, 0x3d228 },
{ 0x46d37, 0x3d229 }, { 0x46d38, 0x3d22b }, { 0x46d39, 0x3d22c },
{ 0x46cd2, 0x3d22d }, { 0x46cd3, 0x3d22e }, { 0x46cd5, 0x3d22f },
{ 0x46cd6, 0x3d230 }, { 0x46cd7, 0x3d231 }, { 0x46cd8, 0x3d232 },
{ 0x46d3a, 0x3d768 }, { 0x46d3b, 0x3d372 }, { 0x46d47, 0x3d43c },
{ 0x46d48, 0x3d7ce }, { 0x46d49, 0x3d7cf }, { 0x46d4a, 0x3d6f1 },
{ 0x46d4b, 0x3d77c }, { 0x46d4c, 0x3d49d }, { 0x46d4d, 0x3d77c },
{ 0x46d4e, 0x3d0b5 }, { 0x46d4f, 0x3d177 }, { 0x46d50, 0x3d2d7 },
{ 0x46d51, 0x3d77c }, { 0x46d52, 0x3d77c }, { 0x46d53, 0x3d30b },
{ 0x46d55, 0x3d706 }, { 0x46d56, 0x3d704 }, { 0x46d57, 0x3d77c },
{ 0x46d54, 0x3d0a0 }, { 0x46d58, 0x3d722 }, { 0x46d5a, 0x3d44a },
{ 0x46d5b, 0x3d452 }, { 0x46d5c, 0x3d469 }, { 0x46d5d, 0x3d475 },
{ 0x46d5e, 0x3d476 }, { 0x46d5f, 0x3d477 }, { 0x46d60, 0x3d478 },
{ 0x46d61, 0x3d479 }, { 0x46d62, 0x3d47a }, { 0x46d63, 0x3d44b },
{ 0x46d64, 0x3d44c }, { 0x46d65, 0x3d44d }, { 0x46d66, 0x3d44e },
{ 0x46d67, 0x3d44f }, { 0x46d68, 0x3d450 }, { 0x46d69, 0x3d451 },
{ 0x46d6a, 0x3d453 }, { 0x46d6b, 0x3d460 }, { 0x46d6c, 0x3d462 },
{ 0x46d6d, 0x3d463 }, { 0x46d6e, 0x3d464 }, { 0x46d6f, 0x3d465 },
{ 0x46d70, 0x3d466 }, { 0x46d71, 0x3d467 }, { 0x46d72, 0x3d468 },
{ 0x46d73, 0x3d454 }, { 0x46d74, 0x3d455 }, { 0x46d75, 0x3d456 },
{ 0x46d76, 0x3d457 }, { 0x46d77, 0x3d458 }, { 0x46d78, 0x3d459 },
{ 0x46d79, 0x3d45a }, { 0x46d7a, 0x3d45b }, { 0x46d7b, 0x3d45c },
{ 0x46d7c, 0x3d45f }, { 0x46d7d, 0x3d461 }, { 0x46d7e, 0x3d46a },
{ 0x46d7f, 0x3d46d }, { 0x46d80, 0x3d46e }, { 0x46d81, 0x3d46f },
{ 0x46d82, 0x3d470 }, { 0x46d83, 0x3d471 }, { 0x46d84, 0x3d472 },
{ 0x46d85, 0x3d473 }, { 0x46d86, 0x3d474 }, { 0x46d87, 0x3d46b },
{ 0x46d88, 0x3d75d }, { 0x46d89, 0x3d75e }, { 0x46d8a, 0x3d75f },
{ 0x46d8b, 0x3d760 }, { 0x46d8c, 0x3d761 }, { 0x46d8d, 0x3d762 },
{ 0x46d8e, 0x3d763 }, { 0x46d8f, 0x3d766 }, { 0x46d90, 0x3d767 },
{ 0x46d91, 0x3d77c }, { 0x46d92, 0x3d768 }, { 0x46d93, 0x3d765 },
{ 0x46d94, 0x3d769 }, { 0x46d95, 0x3d770 }, { 0x46d96, 0x3d775 },
{ 0x46d97, 0x3d776 }, { 0x46d98, 0x3d777 }, { 0x46d99, 0x3d778 },
{ 0x46d9a, 0x3d779 }, { 0x46d9b, 0x3d77a }, { 0x46d9c, 0x3d77b },
{ 0x46d9d, 0x3d764 }, { 0x46d9e, 0x3d739 }, { 0x46d9f, 0x3d73a },
{ 0x46da0, 0x3d73b }, { 0x46da1, 0x3d73c }, { 0x46da2, 0x3d73d },
{ 0x46da3, 0x3d73e }, { 0x46da4, 0x3d742 }, { 0x46da5, 0x3d744 },
{ 0x46da6, 0x3d743 }, { 0x46da7, 0x3d745 }, { 0x46da8, 0x3d741 },
{ 0x46da9, 0x3d746 }, { 0x46daa, 0x3d747 }, { 0x46dab, 0x3d748 },
{ 0x46dac, 0x3d749 }, { 0x46dad, 0x3d74a }, { 0x46dae, 0x3d74b },
{ 0x46daf, 0x3d73f }, { 0x46db0, 0x3d771 }, { 0x46db1, 0x3d74c },
{ 0x46db2, 0x3d74d }, { 0x46db3, 0x3d74e }, { 0x46db4, 0x3d74f },
{ 0x46db5, 0x3d750 }, { 0x46db6, 0x3d751 }, { 0x46db7, 0x3d753 },
{ 0x46db8, 0x3d755 }, { 0x46db9, 0x3d754 }, { 0x46dba, 0x3d756 },
{ 0x46dbb, 0x3d752 }, { 0x46dbc, 0x3d757 }, { 0x46dbd, 0x3d758 },
{ 0x46dbe, 0x3d759 }, { 0x46dbf, 0x3d75a }, { 0x46dc0, 0x3d75b },
{ 0x46dc1, 0x3d75c }, { 0x46dc2, 0x3d4a7 }, { 0x46dc3, 0x3d2bf },
{ 0x46dc4, 0x3d6fa }, { 0x46dc5, 0x3d6f9 }, { 0x46dc6, 0x3d6fb },
{ 0x46dc7, 0x3d6f5 }, { 0x46dc8, 0x3d6fc }, { 0x46dc9, 0x3d6ff },
{ 0x46dca, 0x3d2ab }, { 0x46dcb, 0x3d715 }, { 0x46dcc, 0x3d710 },
{ 0x46dcd, 0x3d70c }, { 0x46dce, 0x3d712 }, { 0x46dcf, 0x3d70f },
{ 0x46dd0, 0x3d717 }, { 0x46dd1, 0x3d716 }, { 0x46dd2, 0x3d285 },
{ 0x46dd3, 0x3d269 }, { 0x46dd4, 0x3d2f8 }, { 0x46dd5, 0x0c421 },
{ 0x46dd6, 0x0c3fc }
};
#define BELLBOT_COUNT_EN 108
static const TagMapping BELLBOT_MAP_EN[108] = {
{ 0x46cd0, 0x31331 }, { 0x46ce2, 0x31332 }, { 0x46ced, 0x31333 },
{ 0x46cf8, 0x31334 }, { 0x46d03, 0x31335 }, { 0x46d0e, 0x31336 },
{ 0x46d19, 0x31337 }, { 0x46d24, 0x31338 }, { 0x46d2f, 0x31339 },
{ 0x46cd1, 0x3133a }, { 0x46cd9, 0x3133b }, { 0x46cda, 0x3133c },
{ 0x46cdb, 0x3133d }, { 0x46cdc, 0x3133e }, { 0x46cdd, 0x3133f },
{ 0x46cde, 0x31340 }, { 0x46cdf, 0x31341 }, { 0x46ce0, 0x31342 },
{ 0x46ce1, 0x31343 }, { 0x46ce3, 0x31344 }, { 0x46ce4, 0x31345 },
{ 0x46ce5, 0x31346 }, { 0x46ce6, 0x31347 }, { 0x46ce7, 0x31348 },
{ 0x46ce8, 0x31349 }, { 0x46ce9, 0x3134a }, { 0x46cea, 0x3134b },
{ 0x46ceb, 0x3134c }, { 0x46cec, 0x3134d }, { 0x46cee, 0x3134e },
{ 0x46cef, 0x3134f }, { 0x46cf0, 0x31350 }, { 0x46cf1, 0x31351 },
{ 0x46cf2, 0x31352 }, { 0x46cf3, 0x31353 }, { 0x46cf4, 0x31354 },
{ 0x46cf5, 0x31355 }, { 0x46cf6, 0x31356 }, { 0x46cf7, 0x31357 },
{ 0x46cf9, 0x31358 }, { 0x46cfa, 0x31359 }, { 0x46cfb, 0x3135a },
{ 0x46cfc, 0x3135b }, { 0x46cfd, 0x3135c }, { 0x46cfe, 0x3135d },
{ 0x46cff, 0x3135e }, { 0x46d00, 0x3135f }, { 0x46d01, 0x31360 },
{ 0x46d02, 0x31361 }, { 0x46d04, 0x31362 }, { 0x46d05, 0x31363 },
{ 0x46d06, 0x31364 }, { 0x46d07, 0x31365 }, { 0x46d08, 0x31366 },
{ 0x46d09, 0x31367 }, { 0x46d0a, 0x31368 }, { 0x46d0b, 0x31369 },
{ 0x46d0c, 0x3136a }, { 0x46d0d, 0x3136b }, { 0x46d0f, 0x3136c },
{ 0x46d10, 0x3136d }, { 0x46d11, 0x3136e }, { 0x46d12, 0x3136f },
{ 0x46d13, 0x31370 }, { 0x46d14, 0x31371 }, { 0x46d15, 0x31372 },
{ 0x46d16, 0x31373 }, { 0x46d17, 0x31374 }, { 0x46d18, 0x31375 },
{ 0x46d1a, 0x31376 }, { 0x46d1b, 0x31377 }, { 0x46d1c, 0x31378 },
{ 0x46d1d, 0x31379 }, { 0x46d1e, 0x3137a }, { 0x46d1f, 0x3137b },
{ 0x46d20, 0x3137c }, { 0x46d21, 0x3137d }, { 0x46d22, 0x3137e },
{ 0x46d23, 0x3137f }, { 0x46d25, 0x31380 }, { 0x46d26, 0x31381 },
{ 0x46d27, 0x31382 }, { 0x46d28, 0x31383 }, { 0x46d29, 0x31384 },
{ 0x46d2a, 0x31385 }, { 0x46d2b, 0x31386 }, { 0x46d2c, 0x31387 },
{ 0x46d2d, 0x31388 }, { 0x46d2e, 0x31389 }, { 0x46d30, 0x3138a },
{ 0x46d31, 0x3138b }, { 0x46d32, 0x3138c }, { 0x46d33, 0x3138d },
{ 0x46d34, 0x3138e }, { 0x46d35, 0x3138f }, { 0x46d36, 0x31390 },
{ 0x46d37, 0x31391 }, { 0x46d38, 0x31392 }, { 0x46d39, 0x31393 },
{ 0x46cd2, 0x31394 }, { 0x46cd3, 0x31395 }, { 0x46cd4, 0x31396 },
{ 0x46cd5, 0x31397 }, { 0x46cd6, 0x31398 }, { 0x46cd7, 0x31399 },
{ 0x46cd8, 0x3139a }, { 0x46d3b, 0x313d7 }, { 0x46d58, 0x313d6 }
};
#define DESKBOT_COUNT_EN 108
static const TagMapping DESKBOT_MAP_EN[108] = {
{ 0x46cd0, 0x3ac00 }, { 0x46ce2, 0x3ac10 }, { 0x46ced, 0x3ac1b },
{ 0x46cf8, 0x3ac26 }, { 0x46d03, 0x3ac31 }, { 0x46d0e, 0x3ac3b },
{ 0x46d19, 0x3ac46 }, { 0x46d24, 0x3ac51 }, { 0x46d2f, 0x3ac5c },
{ 0x46cd1, 0x3ac01 }, { 0x46cd9, 0x3ac07 }, { 0x46cda, 0x3ac08 },
{ 0x46cdb, 0x3ac09 }, { 0x46cdc, 0x3ac0a }, { 0x46cdd, 0x3ac0b },
{ 0x46cde, 0x3ac0c }, { 0x46cdf, 0x3ac0d }, { 0x46ce0, 0x3ac0e },
{ 0x46ce1, 0x3ac0f }, { 0x46ce3, 0x3ac11 }, { 0x46ce4, 0x3ac12 },
{ 0x46ce5, 0x3ac13 }, { 0x46ce6, 0x3ac15 }, { 0x46ce7, 0x3ac16 },
{ 0x46ce8, 0x3ac17 }, { 0x46ce9, 0x3ac18 }, { 0x46cea, 0x3ac19 },
{ 0x46ceb, 0x3ac1a }, { 0x46cec, 0x3ac1c }, { 0x46cee, 0x3abf2 },
{ 0x46cef, 0x3ac1d }, { 0x46cf0, 0x3ac1e }, { 0x46cf1, 0x3ac1f },
{ 0x46cf2, 0x3ac20 }, { 0x46cf3, 0x3ac21 }, { 0x46cf4, 0x3ac22 },
{ 0x46cf5, 0x3ac23 }, { 0x46cf6, 0x3ac24 }, { 0x46cf7, 0x3ac25 },
{ 0x46cf9, 0x3ac27 }, { 0x46cfa, 0x3ac28 }, { 0x46cfb, 0x3ac29 },
{ 0x46cfc, 0x3ac2a }, { 0x46cfd, 0x3ac2b }, { 0x46cfe, 0x3ac2c },
{ 0x46cff, 0x3ac2d }, { 0x46d00, 0x3ac2e }, { 0x46d01, 0x3ac2f },
{ 0x46d02, 0x3ac30 }, { 0x46d04, 0x3ac32 }, { 0x46d05, 0x3ac33 },
{ 0x46d06, 0x3ac34 }, { 0x46d07, 0x3ac35 }, { 0x46d08, 0x3ac36 },
{ 0x46d09, 0x3acd2 }, { 0x46d0a, 0x3ac37 }, { 0x46d0b, 0x3ac38 },
{ 0x46d0c, 0x3ac39 }, { 0x46d0d, 0x3ac3a }, { 0x46d0f, 0x3ac3c },
{ 0x46d10, 0x3ac3d }, { 0x46d11, 0x3ac3e }, { 0x46d12, 0x3ac3f },
{ 0x46d13, 0x3ac40 }, { 0x46d14, 0x3ac41 }, { 0x46d15, 0x3ac42 },
{ 0x46d16, 0x3ac43 }, { 0x46d17, 0x3ac44 }, { 0x46d18, 0x3ac45 },
{ 0x46d1a, 0x3ac47 }, { 0x46d1b, 0x3ac48 }, { 0x46d1c, 0x3ac49 },
{ 0x46d1d, 0x3ac4a }, { 0x46d1e, 0x3ac4b }, { 0x46d1f, 0x3ac4c },
{ 0x46d20, 0x3ac4d }, { 0x46d21, 0x3ac4e }, { 0x46d22, 0x3ac4f },
{ 0x46d23, 0x3ac50 }, { 0x46d25, 0x3ac52 }, { 0x46d26, 0x3ac53 },
{ 0x46d27, 0x3ac54 }, { 0x46d28, 0x3ac55 }, { 0x46d29, 0x3ac56 },
{ 0x46d2a, 0x3ac57 }, { 0x46d2b, 0x3ac58 }, { 0x46d2c, 0x3ac59 },
{ 0x46d2d, 0x3ac5a }, { 0x46d2e, 0x3ac5b }, { 0x46d30, 0x3ac5d },
{ 0x46d31, 0x3ac5e }, { 0x46d32, 0x3ac5f }, { 0x46d33, 0x3ac60 },
{ 0x46d34, 0x3ac61 }, { 0x46d35, 0x3ac62 }, { 0x46d36, 0x3ac63 },
{ 0x46d37, 0x3ac64 }, { 0x46d38, 0x3ac65 }, { 0x46d39, 0x3ac66 },
{ 0x46cd2, 0x3ac02 }, { 0x46cd3, 0x3ac03 }, { 0x46cd4, 0x3ac04 },
{ 0x46cd5, 0x3ac05 }, { 0x46cd6, 0x3ac06 }, { 0x46d3b, 0x3ae27 },
{ 0x46d58, 0x3ae0e }, { 0x46dd2, 0x3aebc }, { 0x46dd6, 0x3aebd }
};
#define DOORBOT_COUNT_EN 240
static const TagMapping DOORBOT_MAP_EN[240] = {
{ 0x46cd1, 0x35ee6 }, { 0x46cd2, 0x35ee7 }, { 0x46cd3, 0x35ee8 },
{ 0x46cd4, 0x35ee9 }, { 0x46cd5, 0x35eea }, { 0x46cd6, 0x35eeb },
{ 0x46cd7, 0x35eec }, { 0x46cd8, 0x35eed }, { 0x46cd9, 0x35eee },
{ 0x46cda, 0x35eef }, { 0x46cdb, 0x35ef0 }, { 0x46cdc, 0x35ef1 },
{ 0x46cdd, 0x35ef2 }, { 0x46cde, 0x35ef3 }, { 0x46cdf, 0x35ef4 },
{ 0x46ce0, 0x35ef5 }, { 0x46ce1, 0x35ef6 }, { 0x46ce2, 0x35ef7 },
{ 0x46ce3, 0x35ef8 }, { 0x46ce4, 0x35ef9 }, { 0x46ce5, 0x35efa },
{ 0x46ce6, 0x35efb }, { 0x46ce7, 0x35efc }, { 0x46ce8, 0x35efd },
{ 0x46ce9, 0x35efe }, { 0x46cea, 0x35eff }, { 0x46ceb, 0x35f00 },
{ 0x46cec, 0x35f01 }, { 0x46ced, 0x35f02 }, { 0x46cee, 0x35f03 },
{ 0x46cef, 0x35f04 }, { 0x46cf0, 0x35f05 }, { 0x46cf1, 0x35f06 },
{ 0x46cf2, 0x35f07 }, { 0x46cf3, 0x35f08 }, { 0x46cf4, 0x35f09 },
{ 0x46cf5, 0x35f0a }, { 0x46cf6, 0x35f0b }, { 0x46cf7, 0x35f0c },
{ 0x46cf8, 0x35f0d }, { 0x46cf9, 0x35f0e }, { 0x46cfa, 0x35f0f },
{ 0x46cfb, 0x35f10 }, { 0x46cfc, 0x35f11 }, { 0x46cfd, 0x35f12 },
{ 0x46cfe, 0x35f13 }, { 0x46cff, 0x35f14 }, { 0x46d00, 0x35f15 },
{ 0x46d01, 0x35f16 }, { 0x46d02, 0x35f17 }, { 0x46d03, 0x35f18 },
{ 0x46d04, 0x35f19 }, { 0x46d05, 0x35f1a }, { 0x46d06, 0x35f1b },
{ 0x46d07, 0x35f1c }, { 0x46d08, 0x35f1d }, { 0x46d09, 0x35f1e },
{ 0x46d0a, 0x35f1f }, { 0x46d0b, 0x35f20 }, { 0x46d0c, 0x35f21 },
{ 0x46d0d, 0x35f22 }, { 0x46d0e, 0x35f23 }, { 0x46d0f, 0x35f24 },
{ 0x46d10, 0x35f25 }, { 0x46d11, 0x35f26 }, { 0x46d12, 0x35f27 },
{ 0x46d13, 0x35f28 }, { 0x46d14, 0x35f29 }, { 0x46d15, 0x35f2a },
{ 0x46d16, 0x35f2b }, { 0x46d17, 0x35f2c }, { 0x46d18, 0x35f2d },
{ 0x46d19, 0x35f2e }, { 0x46d1a, 0x35f2f }, { 0x46d1b, 0x35f30 },
{ 0x46d1c, 0x35f31 }, { 0x46d1d, 0x35f32 }, { 0x46d1e, 0x35f33 },
{ 0x46d1f, 0x35f34 }, { 0x46d20, 0x35f35 }, { 0x46d21, 0x35f36 },
{ 0x46d22, 0x35f37 }, { 0x46d23, 0x35f38 }, { 0x46d24, 0x35f39 },
{ 0x46d25, 0x35f3a }, { 0x46d26, 0x35f3b }, { 0x46d27, 0x35f3c },
{ 0x46d28, 0x35f3d }, { 0x46d29, 0x35f3e }, { 0x46d2a, 0x35f3f },
{ 0x46d2b, 0x35f40 }, { 0x46d2c, 0x35f41 }, { 0x46d2d, 0x35f42 },
{ 0x46d2e, 0x35f43 }, { 0x46d2f, 0x35f44 }, { 0x46d30, 0x35f45 },
{ 0x46d31, 0x35f46 }, { 0x46d32, 0x35f47 }, { 0x46d33, 0x35f48 },
{ 0x46d34, 0x35f49 }, { 0x46d35, 0x35f4a }, { 0x46d36, 0x35f4b },
{ 0x46d37, 0x35f4c }, { 0x46d38, 0x35f4d }, { 0x46d39, 0x35f4e },
{ 0x46d3a, 0x35bf5 }, { 0x46d3b, 0x360c0 }, { 0x46d3d, 0x36027 },
{ 0x46d3e, 0x36028 }, { 0x46d3f, 0x36029 }, { 0x46d40, 0x3602a },
{ 0x46d41, 0x3602e }, { 0x46d42, 0x3602f }, { 0x46d43, 0x36030 },
{ 0x46d44, 0x36031 }, { 0x46d45, 0x3602c }, { 0x46d46, 0x3602d },
{ 0x46d47, 0x36227 }, { 0x46d48, 0x36084 }, { 0x46d49, 0x36085 },
{ 0x46d4a, 0x36467 }, { 0x46d4b, 0x36457 }, { 0x46d4c, 0x36457 },
{ 0x46d4d, 0x36457 }, { 0x46d4e, 0x3646d }, { 0x46d4f, 0x36457 },
{ 0x46d50, 0x36470 }, { 0x46d51, 0x36457 }, { 0x46d52, 0x36457 },
{ 0x46d53, 0x36457 }, { 0x46d55, 0x360a3 }, { 0x46d56, 0x3634c },
{ 0x46d57, 0x36457 }, { 0x46d54, 0x36457 }, { 0x46d58, 0x360bf },
{ 0x46d5a, 0x36407 }, { 0x46d5b, 0x3640c }, { 0x46d5c, 0x3641a },
{ 0x46d5d, 0x36420 }, { 0x46d5e, 0x36421 }, { 0x46d5f, 0x36422 },
{ 0x46d60, 0x36423 }, { 0x46d61, 0x36424 }, { 0x46d66, 0x36408 },
{ 0x46d67, 0x36409 }, { 0x46d68, 0x3640a }, { 0x46d69, 0x3640b },
{ 0x46d6a, 0x3640d }, { 0x46d6e, 0x36415 }, { 0x46d6f, 0x36416 },
{ 0x46d70, 0x36417 }, { 0x46d71, 0x36418 }, { 0x46d72, 0x36419 },
{ 0x46d73, 0x3640e }, { 0x46d74, 0x3640f }, { 0x46d75, 0x36410 },
{ 0x46d76, 0x36411 }, { 0x46d77, 0x36412 }, { 0x46d7e, 0x3641b },
{ 0x46d7f, 0x3641c }, { 0x46d80, 0x3641d }, { 0x46d81, 0x3641e },
{ 0x46d82, 0x3641f }, { 0x46d88, 0x362d4 }, { 0x46d89, 0x362db },
{ 0x46d8a, 0x362e2 }, { 0x46d8b, 0x362e3 }, { 0x46d8c, 0x362e7 },
{ 0x46d8d, 0x362eb }, { 0x46d8e, 0x362f2 }, { 0x46d8f, 0x362f5 },
{ 0x46d90, 0x36305 }, { 0x46d91, 0x36457 }, { 0x46d92, 0x36309 },
{ 0x46d93, 0x362f4 }, { 0x46d94, 0x3630a }, { 0x46d96, 0x36318 },
{ 0x46d97, 0x36319 }, { 0x46d98, 0x36326 }, { 0x46d99, 0x36327 },
{ 0x46d9a, 0x3632e }, { 0x46d9b, 0x3632f }, { 0x46d9c, 0x36330 },
{ 0x46d9d, 0x362f3 }, { 0x46d9e, 0x362b0 }, { 0x46d9f, 0x362b1 },
{ 0x46da0, 0x362b2 }, { 0x46da1, 0x362b3 }, { 0x46da2, 0x362b4 },
{ 0x46da3, 0x362b5 }, { 0x46da4, 0x362b9 }, { 0x46da5, 0x362bb },
{ 0x46da6, 0x362ba }, { 0x46da7, 0x362bc }, { 0x46da8, 0x362b8 },
{ 0x46da9, 0x362bd }, { 0x46daa, 0x362be }, { 0x46dab, 0x362bf },
{ 0x46dac, 0x362c0 }, { 0x46dad, 0x362c1 }, { 0x46dae, 0x362c2 },
{ 0x46daf, 0x362b6 }, { 0x46db0, 0x36314 }, { 0x46db1, 0x362c3 },
{ 0x46db2, 0x362c4 }, { 0x46db3, 0x362c5 }, { 0x46db4, 0x362c6 },
{ 0x46db5, 0x362c7 }, { 0x46db6, 0x362c8 }, { 0x46db7, 0x362ca },
{ 0x46db8, 0x362cc }, { 0x46db9, 0x362cb }, { 0x46dba, 0x362cd },
{ 0x46dbb, 0x362c9 }, { 0x46dbc, 0x362ce }, { 0x46dbd, 0x362cf },
{ 0x46dbe, 0x362d0 }, { 0x46dbf, 0x362d1 }, { 0x46dc0, 0x362d2 },
{ 0x46dc1, 0x362d3 }, { 0x46dc2, 0x3637c }, { 0x46dc3, 0x3627c },
{ 0x46dc4, 0x36497 }, { 0x46dc5, 0x36493 }, { 0x46dc6, 0x3647f },
{ 0x46dc7, 0x3647c }, { 0x46dc8, 0x36482 }, { 0x46dc9, 0x3648a },
{ 0x46dca, 0x3649b }, { 0x46dcb, 0x364b6 }, { 0x46dcc, 0x364aa },
{ 0x46dcd, 0x364a1 }, { 0x46dce, 0x364b0 }, { 0x46dcf, 0x364a7 },
{ 0x46dd1, 0x364b9 }, { 0x46dd2, 0x36370 }, { 0x46dd3, 0x363ab },
{ 0x46dd4, 0x36404 }, { 0x46dd5, 0x362ab }, { 0x46dd6, 0x3636d }
};
#define LIFTBOT_COUNT_EN 118
static const TagMapping LIFTBOT_MAP_EN[118] = {
{ 0x46cd1, 0x335b5 }, { 0x46cd2, 0x33603 }, { 0x46cd3, 0x33604 },
{ 0x46cd4, 0x33605 }, { 0x46cd5, 0x33606 }, { 0x46cd6, 0x33607 },
{ 0x46cd7, 0x33608 }, { 0x46cd8, 0x33607 }, { 0x46cd9, 0x335b6 },
{ 0x46cda, 0x335b7 }, { 0x46cdb, 0x335b8 }, { 0x46cdc, 0x335b9 },
{ 0x46cdd, 0x335ba }, { 0x46cde, 0x335bb }, { 0x46cdf, 0x335bc },
{ 0x46ce0, 0x335bd }, { 0x46ce1, 0x335bf }, { 0x46ce2, 0x335ac },
{ 0x46ce3, 0x335c0 }, { 0x46ce4, 0x335c1 }, { 0x46ce5, 0x335c2 },
{ 0x46ce6, 0x335c4 }, { 0x46ce7, 0x335c5 }, { 0x46ce8, 0x335c6 },
{ 0x46ce9, 0x335c7 }, { 0x46cea, 0x335c8 }, { 0x46ceb, 0x335ca },
{ 0x46cec, 0x335cb }, { 0x46ced, 0x335ad }, { 0x46cee, 0x335cc },
{ 0x46cef, 0x335ce }, { 0x46cf0, 0x335d0 }, { 0x46cf1, 0x335d1 },
{ 0x46cf2, 0x335d2 }, { 0x46cf3, 0x335d4 }, { 0x46cf4, 0x335d5 },
{ 0x46cf5, 0x335d6 }, { 0x46cf6, 0x335d7 }, { 0x46cf7, 0x335d8 },
{ 0x46cf8, 0x335ae }, { 0x46cf9, 0x335d9 }, { 0x46cfa, 0x335db },
{ 0x46cfb, 0x335de }, { 0x46cfc, 0x335df }, { 0x46cfd, 0x335e0 },
{ 0x46cfe, 0x335e1 }, { 0x46cff, 0x335e2 }, { 0x46d00, 0x335e3 },
{ 0x46d01, 0x335e4 }, { 0x46d02, 0x335e5 }, { 0x46d03, 0x335af },
{ 0x46d04, 0x335e6 }, { 0x46d05, 0x335e7 }, { 0x46d06, 0x335ea },
{ 0x46d07, 0x335eb }, { 0x46d08, 0x335ec }, { 0x46d09, 0x3364a },
{ 0x46d0a, 0x3364b }, { 0x46d0b, 0x3364c }, { 0x46d0c, 0x3364d },
{ 0x46d0d, 0x3364e }, { 0x46d0e, 0x335b0 }, { 0x46d0f, 0x33650 },
{ 0x46d10, 0x33651 }, { 0x46d11, 0x33652 }, { 0x46d12, 0x33653 },
{ 0x46d13, 0x33654 }, { 0x46d14, 0x33656 }, { 0x46d15, 0x33657 },
{ 0x46d16, 0x33658 }, { 0x46d17, 0x33659 }, { 0x46d18, 0x3365b },
{ 0x46d19, 0x335b1 }, { 0x46d1a, 0x3365c }, { 0x46d1b, 0x3365d },
{ 0x46d1c, 0x3365e }, { 0x46d1d, 0x3365f }, { 0x46d1e, 0x33660 },
{ 0x46d1f, 0x33661 }, { 0x46d20, 0x33662 }, { 0x46d21, 0x33663 },
{ 0x46d22, 0x335a9 }, { 0x46d23, 0x335aa }, { 0x46d24, 0x335b2 },
{ 0x46d25, 0x335ed }, { 0x46d26, 0x335ee }, { 0x46d27, 0x335ef },
{ 0x46d28, 0x335f0 }, { 0x46d29, 0x335f1 }, { 0x46d2a, 0x335f2 },
{ 0x46d2b, 0x335f4 }, { 0x46d2c, 0x335f5 }, { 0x46d2d, 0x335f6 },
{ 0x46d2e, 0x335f7 }, { 0x46d2f, 0x335b4 }, { 0x46d30, 0x335f8 },
{ 0x46d31, 0x335f9 }, { 0x46d32, 0x335fa }, { 0x46d33, 0x335fb },
{ 0x46d34, 0x335fc }, { 0x46d35, 0x335fd }, { 0x46d36, 0x335ff },
{ 0x46d37, 0x33600 }, { 0x46d38, 0x33601 }, { 0x46d39, 0x33602 },
{ 0x46d3a, 0x3380f }, { 0x46d3b, 0x33695 }, { 0x46d47, 0x07536 },
{ 0x46d4a, 0x3360c }, { 0x46d4e, 0x337fc }, { 0x46d50, 0x337fd },
{ 0x46d56, 0x33800 }, { 0x46d58, 0x33694 }, { 0x46dc2, 0x337f3 },
{ 0x46dc6, 0x337fb }, { 0x46dc7, 0x337f9 }, { 0x46dca, 0x33802 },
{ 0x46dd3, 0x33775 }
};
#define MAITRED_COUNT_EN 108
static const TagMapping MAITRED_MAP_EN[] = {
{ 0x46cd0, 0x3f94c }, { 0x46ce2, 0x3f9a6 }, { 0x46ced, 0x3f9a7 },
{ 0x46cf8, 0x3f9a8 }, { 0x46d03, 0x3f9a9 }, { 0x46d0e, 0x3f9aa },
{ 0x46d19, 0x3f9ab }, { 0x46d24, 0x3f9ac }, { 0x46d2f, 0x3f9ad },
{ 0x46cd1, 0x3f9ae }, { 0x46cd9, 0x3f9af }, { 0x46cda, 0x3f9b0 },
{ 0x46cdb, 0x3f9b1 }, { 0x46cdc, 0x3f9b2 }, { 0x46cdd, 0x3f9b3 },
{ 0x46cde, 0x3f9b4 }, { 0x46cdf, 0x3f9b5 }, { 0x46ce0, 0x3f9b6 },
{ 0x46ce1, 0x3f9b7 }, { 0x46ce3, 0x3f9b8 }, { 0x46ce4, 0x3f9b9 },
{ 0x46ce5, 0x3f9ba }, { 0x46ce6, 0x3f9bb }, { 0x46ce7, 0x3f9bc },
{ 0x46ce8, 0x3f9bd }, { 0x46ce9, 0x3f9be }, { 0x46cea, 0x3f9bf },
{ 0x46ceb, 0x3f9c0 }, { 0x46cec, 0x3f9c1 }, { 0x46cee, 0x3f9c2 },
{ 0x46cef, 0x3f9c3 }, { 0x46cf0, 0x3f9c4 }, { 0x46cf1, 0x3f9c5 },
{ 0x46cf2, 0x3f9c6 }, { 0x46cf3, 0x3f9c7 }, { 0x46cf4, 0x3f9c8 },
{ 0x46cf5, 0x3f9c9 }, { 0x46cf6, 0x3f9ca }, { 0x46cf7, 0x3f9cb },
{ 0x46cf9, 0x3f9cc }, { 0x46cfa, 0x3f9cd }, { 0x46cfb, 0x3f9ce },
{ 0x46cfc, 0x3f9cf }, { 0x46cfd, 0x3f9d0 }, { 0x46cfe, 0x3f9d1 },
{ 0x46cff, 0x3f9d2 }, { 0x46d00, 0x3f9d3 }, { 0x46d01, 0x3f9d4 },
{ 0x46d02, 0x3f9d5 }, { 0x46d04, 0x3f9d6 }, { 0x46d05, 0x3f9d7 },
{ 0x46d06, 0x3f9d9 }, { 0x46d07, 0x3f9da }, { 0x46d08, 0x3f9db },
{ 0x46d09, 0x3f98a }, { 0x46d0a, 0x3f98b }, { 0x46d0b, 0x3f98c },
{ 0x46d0c, 0x3f98d }, { 0x46d0d, 0x3f98e }, { 0x46d0f, 0x3f98f },
{ 0x46d10, 0x3f991 }, { 0x46d11, 0x3f992 }, { 0x46d12, 0x3f993 },
{ 0x46d13, 0x3f994 }, { 0x46d14, 0x3f996 }, { 0x46d15, 0x3f997 },
{ 0x46d16, 0x3f998 }, { 0x46d17, 0x3f999 }, { 0x46d18, 0x3f99a },
{ 0x46d1a, 0x3f99b }, { 0x46d1b, 0x3f99c }, { 0x46d1c, 0x3f99d },
{ 0x46d1d, 0x3f99e }, { 0x46d1e, 0x3f99f }, { 0x46d1f, 0x3f9a1 },
{ 0x46d20, 0x3f9a2 }, { 0x46d21, 0x3f9a3 }, { 0x46d22, 0x3f9a4 },
{ 0x46d23, 0x3f9a5 }, { 0x46d25, 0x3f9dd }, { 0x46d26, 0x3f9de },
{ 0x46d27, 0x3f9df }, { 0x46d28, 0x3f9e0 }, { 0x46d29, 0x3f9e1 },
{ 0x46d2a, 0x3f9e2 }, { 0x46d2b, 0x3f9e3 }, { 0x46d2c, 0x3f9e4 },
{ 0x46d2d, 0x3f9e5 }, { 0x46d2e, 0x3f9e6 }, { 0x46d30, 0x3f9e7 },
{ 0x46d31, 0x3f9e8 }, { 0x46d32, 0x3f9e9 }, { 0x46d33, 0x3f9ea },
{ 0x46d34, 0x3f9eb }, { 0x46d35, 0x3f9ec }, { 0x46d36, 0x3f9ed },
{ 0x46d37, 0x3f9ee }, { 0x46d38, 0x3f9ef }, { 0x46d39, 0x3f9f0 },
{ 0x46cd2, 0x3f9f1 }, { 0x46cd3, 0x3f9f2 }, { 0x46cd4, 0x3f9f3 },
{ 0x46cd5, 0x3f9f9 }, { 0x46cd6, 0x3f9fa }, { 0x46cd7, 0x3f9fb },
{ 0x46cd8, 0x3f9fc }, { 0x46d3b, 0x3f853 }, { 0x46d58, 0x3f83c }
};
#define BARBOT_COUNT_DE 229
static const TagMapping BARBOT_MAP_DE[229] = {
{ 0x46cd0, 0x3d21e }, { 0x46ce2, 0x3d23b }, { 0x46ced, 0x3d246 },
{ 0x46cf8, 0x3d251 }, { 0x46d03, 0x3d25c }, { 0x46d0e, 0x3d267 },
{ 0x46d19, 0x3d272 }, { 0x46d24, 0x3d27d }, { 0x46d2f, 0x3d288 },
{ 0x46cd1, 0x3d21f }, { 0x46cd9, 0x3d22a }, { 0x46cda, 0x3d233 },
{ 0x46cdb, 0x3d234 }, { 0x46cdc, 0x3d235 }, { 0x46cdd, 0x3d236 },
{ 0x46cde, 0x3d237 }, { 0x46cdf, 0x3d238 }, { 0x46ce0, 0x3d239 },
{ 0x46ce1, 0x3d23a }, { 0x46ce3, 0x3d23c }, { 0x46ce4, 0x3d23d },
{ 0x46ce5, 0x3d23e }, { 0x46ce6, 0x3d23f }, { 0x46ce7, 0x3d240 },
{ 0x46ce8, 0x3d241 }, { 0x46ce9, 0x3d242 }, { 0x46cea, 0x3d243 },
{ 0x46ceb, 0x3d244 }, { 0x46cec, 0x3d245 }, { 0x46cee, 0x3d26b },
{ 0x46cef, 0x3d247 }, { 0x46cf0, 0x3d248 }, { 0x46cf1, 0x3d249 },
{ 0x46cf2, 0x3d24a }, { 0x46cf3, 0x3d24b }, { 0x46cf4, 0x3d24c },
{ 0x46cf5, 0x3d24d }, { 0x46cf6, 0x3d24e }, { 0x46cf7, 0x3d24f },
{ 0x46cf9, 0x3d250 }, { 0x46cfa, 0x3d252 }, { 0x46cfb, 0x3d253 },
{ 0x46cfc, 0x3d254 }, { 0x46cfd, 0x3d255 }, { 0x46cfe, 0x3d256 },
{ 0x46cff, 0x3d257 }, { 0x46d00, 0x3d258 }, { 0x46d01, 0x3d259 },
{ 0x46d02, 0x3d25a }, { 0x46d04, 0x3d25b }, { 0x46d05, 0x3d25d },
{ 0x46d06, 0x3d25e }, { 0x46d07, 0x3d25f }, { 0x46d08, 0x3d260 },
{ 0x46d09, 0x3d26f }, { 0x46d0a, 0x3d270 }, { 0x46d0b, 0x3d271 },
{ 0x46d0c, 0x3d273 }, { 0x46d0d, 0x3d274 }, { 0x46d0f, 0x3d275 },
{ 0x46d10, 0x3d276 }, { 0x46d11, 0x3d277 }, { 0x46d12, 0x3d278 },
{ 0x46d13, 0x3d279 }, { 0x46d1d, 0x3d283 }, { 0x46d1e, 0x3d284 },
{ 0x46d1f, 0x3d285 }, { 0x46d20, 0x3d286 }, { 0x46d21, 0x3d287 },
{ 0x46d22, 0x3d289 }, { 0x46d23, 0x3d28a }, { 0x46d25, 0x3d28b },
{ 0x46d26, 0x3d28c }, { 0x46d27, 0x3d28d }, { 0x46d28, 0x3d28e },
{ 0x46d29, 0x3d28f }, { 0x46d2a, 0x3d290 }, { 0x46d2b, 0x3d291 },
{ 0x46d2c, 0x3d292 }, { 0x46cd2, 0x3d22d }, { 0x46cd3, 0x3d22e },
{ 0x46cd5, 0x3d22f }, { 0x46cd6, 0x3d230 }, { 0x46cd7, 0x3d231 },
{ 0x46cd8, 0x3d232 }, { 0x46d3a, 0x3d768 }, { 0x46d3b, 0x3d372 },
{ 0x46d48, 0x3d7ce }, { 0x46d49, 0x3d7cf }, { 0x46d4a, 0x3d6f1 },
{ 0x46d4b, 0x3d77c }, { 0x46d4c, 0x3d49d }, { 0x46d4d, 0x3d77c },
{ 0x46d4e, 0x3d0b5 }, { 0x46d4f, 0x3d177 }, { 0x46d50, 0x3d2d7 },
{ 0x46d51, 0x3d77c }, { 0x46d52, 0x3d77c }, { 0x46d53, 0x3d30b },
{ 0x46d55, 0x3d706 }, { 0x46d56, 0x3d704 }, { 0x46d57, 0x3d77c },
{ 0x46d54, 0x3d0a0 }, { 0x46d58, 0x3d722 }, { 0x46d5a, 0x3d44a },
{ 0x46d5b, 0x3d452 }, { 0x46d5c, 0x3d469 }, { 0x46d5d, 0x3d475 },
{ 0x46d5e, 0x3d476 }, { 0x46d5f, 0x3d477 }, { 0x46d60, 0x3d478 },
{ 0x46d61, 0x3d479 }, { 0x46d62, 0x3d47a }, { 0x46d63, 0x3d44b },
{ 0x46d64, 0x3d44c }, { 0x46d65, 0x3d44d }, { 0x46d66, 0x3d44e },
{ 0x46d67, 0x3d44f }, { 0x46d68, 0x3d450 }, { 0x46d69, 0x3d451 },
{ 0x46d6a, 0x3d453 }, { 0x46d6b, 0x3d460 }, { 0x46d6c, 0x3d462 },
{ 0x46d6d, 0x3d463 }, { 0x46d6e, 0x3d464 }, { 0x46d6f, 0x3d465 },
{ 0x46d70, 0x3d466 }, { 0x46d71, 0x3d467 }, { 0x46d72, 0x3d468 },
{ 0x46d73, 0x3d454 }, { 0x46d74, 0x3d455 }, { 0x46d75, 0x3d456 },
{ 0x46d76, 0x3d457 }, { 0x46d77, 0x3d458 }, { 0x46d78, 0x3d459 },
{ 0x46d79, 0x3d45a }, { 0x46d7a, 0x3d45b }, { 0x46d7b, 0x3d45c },
{ 0x46d7c, 0x3d45f }, { 0x46d7d, 0x3d461 }, { 0x46d7e, 0x3d46a },
{ 0x46d7f, 0x3d46d }, { 0x46d80, 0x3d46e }, { 0x46d81, 0x3d46f },
{ 0x46d82, 0x3d470 }, { 0x46d83, 0x3d471 }, { 0x46d84, 0x3d472 },
{ 0x46d85, 0x3d473 }, { 0x46d86, 0x3d474 }, { 0x46d87, 0x3d46b },
{ 0x46d88, 0x3d75d }, { 0x46d89, 0x3d75e }, { 0x46d8a, 0x3d75f },
{ 0x46d8b, 0x3d760 }, { 0x46d8c, 0x3d761 }, { 0x46d8d, 0x3d762 },
{ 0x46d8e, 0x3d763 }, { 0x46d8f, 0x3d766 }, { 0x46d90, 0x3d767 },
{ 0x46d91, 0x3d77c }, { 0x46d92, 0x3d768 }, { 0x46d93, 0x3d765 },
{ 0x46d94, 0x3d769 }, { 0x46d95, 0x3d770 }, { 0x46d96, 0x3d775 },
{ 0x46d97, 0x3d776 }, { 0x46d98, 0x3d777 }, { 0x46d99, 0x3d778 },
{ 0x46d9a, 0x3d779 }, { 0x46d9b, 0x3d77a }, { 0x46d9c, 0x3d77b },
{ 0x46d9d, 0x3d764 }, { 0x46d9e, 0x3d739 }, { 0x46d9f, 0x3d73a },
{ 0x46da0, 0x3d73b }, { 0x46da1, 0x3d73c }, { 0x46da2, 0x3d73d },
{ 0x46da3, 0x3d73e }, { 0x46da4, 0x3d742 }, { 0x46da5, 0x3d744 },
{ 0x46da6, 0x3d743 }, { 0x46da7, 0x3d745 }, { 0x46da8, 0x3d741 },
{ 0x46da9, 0x3d746 }, { 0x46daa, 0x3d747 }, { 0x46dab, 0x3d748 },
{ 0x46dac, 0x3d749 }, { 0x46dad, 0x3d74a }, { 0x46dae, 0x3d74b },
{ 0x46daf, 0x3d73f }, { 0x46db0, 0x3d771 }, { 0x46db1, 0x3d74c },
{ 0x46db2, 0x3d74d }, { 0x46db3, 0x3d74e }, { 0x46db4, 0x3d74f },
{ 0x46db5, 0x3d750 }, { 0x46db6, 0x3d751 }, { 0x46db7, 0x3d753 },
{ 0x46db8, 0x3d755 }, { 0x46db9, 0x3d754 }, { 0x46dba, 0x3d756 },
{ 0x46dbb, 0x3d752 }, { 0x46dbc, 0x3d757 }, { 0x46dbd, 0x3d758 },
{ 0x46dbe, 0x3d759 }, { 0x46dbf, 0x3d75a }, { 0x46dc0, 0x3d75b },
{ 0x46dc1, 0x3d75c }, { 0x46dc2, 0x3d4a7 }, { 0x46dc3, 0x3d2bf },
{ 0x46dc4, 0x3d6fa }, { 0x46dc5, 0x3d6f9 }, { 0x46dc6, 0x3d6fb },
{ 0x46dc7, 0x3d6f5 }, { 0x46dc8, 0x3d6fc }, { 0x46dc9, 0x3d6ff },
{ 0x46dca, 0x3d2ab }, { 0x46dcb, 0x3d715 }, { 0x46dcc, 0x3d710 },
{ 0x46dcd, 0x3d70c }, { 0x46dce, 0x3d712 }, { 0x46dcf, 0x3d70f },
{ 0x46dd0, 0x3d717 }, { 0x46dd1, 0x3d716 }, { 0x46dd2, 0x3d285 },
{ 0x46dd3, 0x3d269 }, { 0x46dd4, 0x3d2f8 }, { 0x46dd5, 0x0c429 },
{ 0x46dd6, 0x0c400 }
};
#define BELLBOT_COUNT_DE 108
static const TagMapping BELLBOT_MAP_DE[108] = {
{ 0x46cd0, 0x31331 }, { 0x46ce2, 0x31332 }, { 0x46ced, 0x31333 },
{ 0x46cf8, 0x31334 }, { 0x46d03, 0x31335 }, { 0x46d0e, 0x31336 },
{ 0x46d19, 0x31337 }, { 0x46d24, 0x31338 }, { 0x46d2f, 0x31339 },
{ 0x46cd1, 0x3133a }, { 0x46cd9, 0x3133b }, { 0x46cda, 0x3133c },
{ 0x46cdb, 0x3133d }, { 0x46cdc, 0x3133e }, { 0x46cdd, 0x3133f },
{ 0x46cde, 0x31340 }, { 0x46cdf, 0x31341 }, { 0x46ce0, 0x31342 },
{ 0x46ce1, 0x31343 }, { 0x46ce3, 0x31344 }, { 0x46ce4, 0x31345 },
{ 0x46ce5, 0x31346 }, { 0x46ce6, 0x31347 }, { 0x46ce7, 0x31348 },
{ 0x46ce8, 0x31349 }, { 0x46ce9, 0x3134a }, { 0x46cea, 0x3134b },
{ 0x46ceb, 0x3134c }, { 0x46cec, 0x3134d }, { 0x46cee, 0x3134e },
{ 0x46cef, 0x3134f }, { 0x46cf0, 0x31350 }, { 0x46cf1, 0x31351 },
{ 0x46cf2, 0x31352 }, { 0x46cf3, 0x31353 }, { 0x46cf4, 0x31354 },
{ 0x46cf5, 0x31355 }, { 0x46cf6, 0x31356 }, { 0x46cf7, 0x31357 },
{ 0x46cf9, 0x31358 }, { 0x46cfa, 0x31359 }, { 0x46cfb, 0x3135a },
{ 0x46cfc, 0x3135b }, { 0x46cfd, 0x3135c }, { 0x46cfe, 0x3135d },
{ 0x46cff, 0x3135e }, { 0x46d00, 0x3135f }, { 0x46d01, 0x31360 },
{ 0x46d02, 0x31361 }, { 0x46d04, 0x31362 }, { 0x46d05, 0x31363 },
{ 0x46d06, 0x31364 }, { 0x46d07, 0x31365 }, { 0x46d08, 0x31366 },
{ 0x46d09, 0x31367 }, { 0x46d0a, 0x31368 }, { 0x46d0b, 0x31369 },
{ 0x46d0c, 0x3136a }, { 0x46d0d, 0x3136b }, { 0x46d0f, 0x3136c },
{ 0x46d10, 0x3136d }, { 0x46d11, 0x3136e }, { 0x46d12, 0x3136f },
{ 0x46d13, 0x31370 }, { 0x46d14, 0x31371 }, { 0x46d15, 0x31372 },
{ 0x46d16, 0x31373 }, { 0x46d17, 0x31374 }, { 0x46d18, 0x31375 },
{ 0x46d1a, 0x31376 }, { 0x46d1b, 0x31377 }, { 0x46d1c, 0x31378 },
{ 0x46d1d, 0x31379 }, { 0x46d1e, 0x3137a }, { 0x46d1f, 0x3137b },
{ 0x46d20, 0x3137c }, { 0x46d21, 0x3137d }, { 0x46d22, 0x3137e },
{ 0x46d23, 0x3137f }, { 0x46d25, 0x31380 }, { 0x46d26, 0x31381 },
{ 0x46d27, 0x31382 }, { 0x46d28, 0x31383 }, { 0x46d29, 0x31384 },
{ 0x46d2a, 0x31385 }, { 0x46d2b, 0x31386 }, { 0x46d2c, 0x31387 },
{ 0x46d2d, 0x31388 }, { 0x46d2e, 0x31389 }, { 0x46d30, 0x3138a },
{ 0x46d31, 0x3138b }, { 0x46d32, 0x3138c }, { 0x46d33, 0x3138d },
{ 0x46d34, 0x3138e }, { 0x46d35, 0x3138f }, { 0x46d36, 0x31390 },
{ 0x46d37, 0x31391 }, { 0x46d38, 0x31392 }, { 0x46d39, 0x31393 },
{ 0x46cd2, 0x31394 }, { 0x46cd3, 0x31395 }, { 0x46cd4, 0x31396 },
{ 0x46cd5, 0x31397 }, { 0x46cd6, 0x31398 }, { 0x46cd7, 0x31399 },
{ 0x46cd8, 0x3139a }, { 0x46d3b, 0x313d7 }, { 0x46d58, 0x313d6 }
};
#define DESKBOT_COUNT_DE 101
static const TagMapping DESKBOT_MAP_DE[101] = {
{ 0x46cd0, 0x3ac00 }, { 0x46ce2, 0x3ac10 }, { 0x46ced, 0x3ac1b },
{ 0x46cf8, 0x3ac26 }, { 0x46d03, 0x3ac31 }, { 0x46d0e, 0x3ac3b },
{ 0x46d19, 0x3ac46 }, { 0x46d24, 0x3ac51 }, { 0x46d2f, 0x3ac5c },
{ 0x46cd1, 0x3ac01 }, { 0x46cd9, 0x3ac07 }, { 0x46cda, 0x3ac08 },
{ 0x46cdb, 0x3ac09 }, { 0x46cdc, 0x3ac0a }, { 0x46cdf, 0x3ac0d },
{ 0x46ce0, 0x3ac0e }, { 0x46ce1, 0x3ac0f }, { 0x46ce3, 0x3ac11 },
{ 0x46ce4, 0x3ac12 }, { 0x46ce5, 0x3ac13 }, { 0x46ce6, 0x3ac15 },
{ 0x46ce7, 0x3ac16 }, { 0x46ce8, 0x3ac17 }, { 0x46ce9, 0x3ac18 },
{ 0x46cea, 0x3ac19 }, { 0x46ceb, 0x3ac1a }, { 0x46cec, 0x3ac1c },
{ 0x46cee, 0x3abf2 }, { 0x46cef, 0x3ac1d }, { 0x46cf0, 0x3ac1e },
{ 0x46cf3, 0x3ac21 }, { 0x46cf4, 0x3ac22 }, { 0x46cf5, 0x3ac23 },
{ 0x46cf6, 0x3ac24 }, { 0x46cf7, 0x3ac25 }, { 0x46cf9, 0x3ac27 },
{ 0x46cfa, 0x3ac28 }, { 0x46cfb, 0x3ac29 }, { 0x46cfc, 0x3ac2a },
{ 0x46cfd, 0x3ac2b }, { 0x46cfe, 0x3ac2c }, { 0x46cff, 0x3ac2d },
{ 0x46d00, 0x3ac2e }, { 0x46d01, 0x3ac2f }, { 0x46d04, 0x3ac32 },
{ 0x46d05, 0x3ac33 }, { 0x46d08, 0x3ac36 }, { 0x46d09, 0x3acd2 },
{ 0x46d0a, 0x3ac37 }, { 0x46d0b, 0x3ac38 }, { 0x46d0c, 0x3ac39 },
{ 0x46d0d, 0x3ac3a }, { 0x46d0f, 0x3ac3c }, { 0x46d10, 0x3ac3d },
{ 0x46d11, 0x3ac3e }, { 0x46d12, 0x3ac3f }, { 0x46d13, 0x3ac40 },
{ 0x46d14, 0x3ac41 }, { 0x46d15, 0x3ac42 }, { 0x46d16, 0x3ac43 },
{ 0x46d17, 0x3ac44 }, { 0x46d18, 0x3ac45 }, { 0x46d1a, 0x3ac47 },
{ 0x46d1b, 0x3ac48 }, { 0x46d1c, 0x3ac49 }, { 0x46d1d, 0x3ac4a },
{ 0x46d1e, 0x3ac4b }, { 0x46d1f, 0x3ac4c }, { 0x46d20, 0x3ac4d },
{ 0x46d21, 0x3ac4e }, { 0x46d22, 0x3ac4f }, { 0x46d23, 0x3ac50 },
{ 0x46d25, 0x3ac52 }, { 0x46d26, 0x3ac53 }, { 0x46d27, 0x3ac54 },
{ 0x46d28, 0x3ac55 }, { 0x46d29, 0x3ac56 }, { 0x46d2a, 0x3ac57 },
{ 0x46d2b, 0x3ac58 }, { 0x46d2c, 0x3ac59 }, { 0x46d2d, 0x3ac5a },
{ 0x46d2e, 0x3ac5b }, { 0x46d30, 0x3ac5d }, { 0x46d31, 0x3ac5e },
{ 0x46d32, 0x3ac5f }, { 0x46d33, 0x3ac60 }, { 0x46d34, 0x3ac61 },
{ 0x46d35, 0x3ac62 }, { 0x46d36, 0x3ac63 }, { 0x46d37, 0x3ac64 },
{ 0x46d38, 0x3ac65 }, { 0x46d39, 0x3ac66 }, { 0x46cd2, 0x3ac02 },
{ 0x46cd3, 0x3ac03 }, { 0x46cd4, 0x3ac04 }, { 0x46cd5, 0x3ac05 },
{ 0x46cd6, 0x3ac06 }, { 0x46d3b, 0x3ae27 }, { 0x46d58, 0x3ae0e },
{ 0x46dd2, 0x3aebc }, { 0x46dd6, 0x3aebd }
};
#define DOORBOT_COUNT_DE 234
static const TagMapping DOORBOT_MAP_DE[234] = {
{ 0x46cd0, 0x35ee5 }, { 0x46cd1, 0x35ee6 }, { 0x46cd2, 0x35ee7 },
{ 0x46cd3, 0x35ee8 }, { 0x46cd4, 0x35ee9 }, { 0x46cd5, 0x35eea },
{ 0x46cd6, 0x35eeb }, { 0x46cd7, 0x35eec }, { 0x46cd8, 0x35eed },
{ 0x46cd9, 0x35eee }, { 0x46cda, 0x35eef }, { 0x46cdb, 0x35ef0 },
{ 0x46cdc, 0x35ef1 }, { 0x46cdd, 0x35ef2 }, { 0x46cde, 0x35ef3 },
{ 0x46cdf, 0x35ef4 }, { 0x46ce0, 0x35ef5 }, { 0x46ce1, 0x35ef6 },
{ 0x46ce2, 0x35ef7 }, { 0x46ce3, 0x35ef8 }, { 0x46ce4, 0x35ef9 },
{ 0x46ce5, 0x35efa }, { 0x46ce6, 0x35efb }, { 0x46ce7, 0x35efc },
{ 0x46ce8, 0x35efd }, { 0x46ce9, 0x35efe }, { 0x46cea, 0x35eff },
{ 0x46ceb, 0x35f00 }, { 0x46cec, 0x35f01 }, { 0x46ced, 0x35f02 },
{ 0x46cee, 0x35f03 }, { 0x46cef, 0x35f04 }, { 0x46cf0, 0x35f05 },
{ 0x46cf1, 0x35f06 }, { 0x46cf2, 0x35f07 }, { 0x46cf3, 0x35f08 },
{ 0x46cf4, 0x35f09 }, { 0x46cf5, 0x35f0a }, { 0x46cf6, 0x35f0b },
{ 0x46cf7, 0x35f0c }, { 0x46cf8, 0x35f0d }, { 0x46cf9, 0x35f0e },
{ 0x46cfa, 0x35f0f }, { 0x46cfb, 0x35f10 }, { 0x46cfc, 0x35f11 },
{ 0x46cfd, 0x35f12 }, { 0x46cfe, 0x35f13 }, { 0x46cff, 0x35f14 },
{ 0x46d00, 0x35f15 }, { 0x46d01, 0x35f16 }, { 0x46d02, 0x35f17 },
{ 0x46d03, 0x35f18 }, { 0x46d04, 0x35f19 }, { 0x46d05, 0x35f1a },
{ 0x46d06, 0x35f1b }, { 0x46d07, 0x35f1c }, { 0x46d08, 0x35f1d },
{ 0x46d09, 0x35f1e }, { 0x46d0a, 0x35f1f }, { 0x46d0b, 0x35f20 },
{ 0x46d0c, 0x35f21 }, { 0x46d0d, 0x35f22 }, { 0x46d0e, 0x35f23 },
{ 0x46d0f, 0x35f24 }, { 0x46d10, 0x35f25 }, { 0x46d11, 0x35f26 },
{ 0x46d12, 0x35f27 }, { 0x46d13, 0x35f28 }, { 0x46d14, 0x35f29 },
{ 0x46d15, 0x35f2a }, { 0x46d16, 0x35f2b }, { 0x46d17, 0x35f2c },
{ 0x46d18, 0x35f2d }, { 0x46d19, 0x35f2e }, { 0x46d1a, 0x35f2f },
{ 0x46d1d, 0x35f32 }, { 0x46d20, 0x35f35 }, { 0x46d21, 0x35f36 },
{ 0x46d22, 0x35f37 }, { 0x46d23, 0x35f38 }, { 0x46d24, 0x35f39 },
{ 0x46d25, 0x35f3a }, { 0x46d26, 0x35f3b }, { 0x46d27, 0x35f3c },
{ 0x46d28, 0x35f3d }, { 0x46d29, 0x35f3e }, { 0x46d2a, 0x35f3f },
{ 0x46d2b, 0x35f40 }, { 0x46d2c, 0x35f41 }, { 0x46d2d, 0x35f42 },
{ 0x46d2e, 0x35f43 }, { 0x46d2f, 0x35f44 }, { 0x46d30, 0x35f45 },
{ 0x46d31, 0x35f46 }, { 0x46d32, 0x35f47 }, { 0x46d33, 0x35f48 },
{ 0x46d34, 0x35f49 }, { 0x46d35, 0x35f4a }, { 0x46d36, 0x35f4b },
{ 0x46d37, 0x35f4c }, { 0x46d38, 0x35f4d }, { 0x46d39, 0x35f4e },
{ 0x46d3a, 0x35bf5 }, { 0x46d3b, 0x360c0 }, { 0x46d3d, 0x36027 },
{ 0x46d3e, 0x36028 }, { 0x46d3f, 0x36029 }, { 0x46d40, 0x3602a },
{ 0x46d41, 0x3602e }, { 0x46d42, 0x3602f }, { 0x46d43, 0x36030 },
{ 0x46d44, 0x36031 }, { 0x46d45, 0x3602c }, { 0x46d46, 0x3602d },
{ 0x46d47, 0x36227 }, { 0x46d4a, 0x36467 }, { 0x46d4b, 0x36457 },
{ 0x46d4c, 0x36457 }, { 0x46d4d, 0x36457 }, { 0x46d4e, 0x3646d },
{ 0x46d4f, 0x36457 }, { 0x46d50, 0x36470 }, { 0x46d51, 0x36457 },
{ 0x46d52, 0x36457 }, { 0x46d53, 0x36457 }, { 0x46d55, 0x360a3 },
{ 0x46d56, 0x3634c }, { 0x46d57, 0x36457 }, { 0x46d54, 0x36457 },
{ 0x46d58, 0x360bf }, { 0x46d5a, 0x36407 }, { 0x46d5b, 0x3640c },
{ 0x46d5c, 0x3641a }, { 0x46d5d, 0x36420 }, { 0x46d5f, 0x36422 },
{ 0x46d60, 0x36423 }, { 0x46d61, 0x36424 }, { 0x46d66, 0x36408 },
{ 0x46d67, 0x36409 }, { 0x46d68, 0x3640a }, { 0x46d69, 0x3640b },
{ 0x46d6a, 0x3640d }, { 0x46d6e, 0x36415 }, { 0x46d6f, 0x36416 },
{ 0x46d70, 0x36417 }, { 0x46d71, 0x36418 }, { 0x46d72, 0x36419 },
{ 0x46d73, 0x3640e }, { 0x46d74, 0x3640f }, { 0x46d75, 0x36410 },
{ 0x46d76, 0x36411 }, { 0x46d77, 0x36412 }, { 0x46d7e, 0x3641b },
{ 0x46d7f, 0x3641c }, { 0x46d80, 0x3641d }, { 0x46d81, 0x3641e },
{ 0x46d82, 0x3641f }, { 0x46d88, 0x362d4 }, { 0x46d89, 0x362db },
{ 0x46d8a, 0x362e2 }, { 0x46d8b, 0x362e3 }, { 0x46d8c, 0x362e7 },
{ 0x46d8d, 0x362eb }, { 0x46d8e, 0x362f2 }, { 0x46d8f, 0x362f5 },
{ 0x46d90, 0x36305 }, { 0x46d91, 0x36457 }, { 0x46d92, 0x36309 },
{ 0x46d93, 0x362f4 }, { 0x46d94, 0x3630a }, { 0x46d96, 0x36318 },
{ 0x46d97, 0x36319 }, { 0x46d98, 0x36326 }, { 0x46d99, 0x36327 },
{ 0x46d9a, 0x3632e }, { 0x46d9b, 0x3632f }, { 0x46d9c, 0x36330 },
{ 0x46d9d, 0x362f3 }, { 0x46d9e, 0x362b0 }, { 0x46d9f, 0x362b1 },
{ 0x46da0, 0x362b2 }, { 0x46da1, 0x362b3 }, { 0x46da2, 0x362b4 },
{ 0x46da3, 0x362b5 }, { 0x46da4, 0x362b9 }, { 0x46da5, 0x362bb },
{ 0x46da6, 0x362ba }, { 0x46da7, 0x362bc }, { 0x46da8, 0x362b8 },
{ 0x46da9, 0x362bd }, { 0x46daa, 0x362be }, { 0x46dab, 0x362bf },
{ 0x46dac, 0x362c0 }, { 0x46dad, 0x362c1 }, { 0x46dae, 0x362c2 },
{ 0x46daf, 0x362b6 }, { 0x46db0, 0x36314 }, { 0x46db1, 0x362c3 },
{ 0x46db2, 0x362c4 }, { 0x46db3, 0x362c5 }, { 0x46db4, 0x362c6 },
{ 0x46db5, 0x362c7 }, { 0x46db6, 0x362c8 }, { 0x46db7, 0x362ca },
{ 0x46db8, 0x362cc }, { 0x46db9, 0x362cb }, { 0x46dba, 0x362cd },
{ 0x46dbb, 0x362c9 }, { 0x46dbc, 0x362ce }, { 0x46dbd, 0x362cf },
{ 0x46dbe, 0x362d0 }, { 0x46dbf, 0x362d1 }, { 0x46dc0, 0x362d2 },
{ 0x46dc1, 0x362d3 }, { 0x46dc2, 0x3637c }, { 0x46dc3, 0x3627c },
{ 0x46dc4, 0x36497 }, { 0x46dc5, 0x36493 }, { 0x46dc6, 0x3647f },
{ 0x46dc7, 0x3647c }, { 0x46dc8, 0x36482 }, { 0x46dc9, 0x3648a },
{ 0x46dca, 0x3649b }, { 0x46dcb, 0x364b6 }, { 0x46dcc, 0x364aa },
{ 0x46dcd, 0x364a1 }, { 0x46dce, 0x364b0 }, { 0x46dcf, 0x364a7 },
{ 0x46dd1, 0x364b9 }, { 0x46dd2, 0x36370 }, { 0x46dd3, 0x363ab },
{ 0x46dd4, 0x36404 }, { 0x46dd5, 0x362ab }, { 0x46dd6, 0x3636d }
};
#define LIFTBOT_COUNT_DE 119
static const TagMapping LIFTBOT_MAP_DE[119] = {
{ 0x46cd0, 0x335ab }, { 0x46cd1, 0x335b5 }, { 0x46cd2, 0x33603 },
{ 0x46cd3, 0x33604 }, { 0x46cd4, 0x33605 }, { 0x46cd5, 0x33606 },
{ 0x46cd6, 0x33607 }, { 0x46cd7, 0x33608 }, { 0x46cd8, 0x33607 },
{ 0x46cd9, 0x335b6 }, { 0x46cda, 0x335b7 }, { 0x46cdb, 0x335b8 },
{ 0x46cdc, 0x335b9 }, { 0x46cdd, 0x335ba }, { 0x46cde, 0x335bb },
{ 0x46cdf, 0x335bc }, { 0x46ce0, 0x335bd }, { 0x46ce1, 0x335bf },
{ 0x46ce2, 0x335ac }, { 0x46ce3, 0x335c0 }, { 0x46ce4, 0x335c1 },
{ 0x46ce5, 0x335c2 }, { 0x46ce6, 0x335c4 }, { 0x46ce7, 0x335c5 },
{ 0x46ce8, 0x335c6 }, { 0x46ce9, 0x335c7 }, { 0x46cea, 0x335c8 },
{ 0x46ceb, 0x335ca }, { 0x46cec, 0x335cb }, { 0x46ced, 0x335ad },
{ 0x46cee, 0x335cc }, { 0x46cef, 0x335ce }, { 0x46cf0, 0x335d0 },
{ 0x46cf1, 0x335d1 }, { 0x46cf2, 0x335d2 }, { 0x46cf3, 0x335d4 },
{ 0x46cf4, 0x335d5 }, { 0x46cf5, 0x335d6 }, { 0x46cf6, 0x335d7 },
{ 0x46cf7, 0x335d8 }, { 0x46cf8, 0x335ae }, { 0x46cf9, 0x335d9 },
{ 0x46cfa, 0x335db }, { 0x46cfb, 0x335de }, { 0x46cfc, 0x335df },
{ 0x46cfd, 0x335e0 }, { 0x46cfe, 0x335e1 }, { 0x46cff, 0x335e2 },
{ 0x46d00, 0x335e3 }, { 0x46d01, 0x335e4 }, { 0x46d02, 0x335e5 },
{ 0x46d03, 0x335af }, { 0x46d04, 0x335e6 }, { 0x46d05, 0x335e7 },
{ 0x46d06, 0x335ea }, { 0x46d07, 0x335eb }, { 0x46d08, 0x335ec },
{ 0x46d09, 0x3364a }, { 0x46d0a, 0x3364b }, { 0x46d0b, 0x3364c },
{ 0x46d0c, 0x3364d }, { 0x46d0d, 0x3364e }, { 0x46d0e, 0x335b0 },
{ 0x46d0f, 0x33650 }, { 0x46d10, 0x33651 }, { 0x46d11, 0x33652 },
{ 0x46d12, 0x33653 }, { 0x46d13, 0x33654 }, { 0x46d14, 0x33656 },
{ 0x46d15, 0x33657 }, { 0x46d16, 0x33658 }, { 0x46d17, 0x33659 },
{ 0x46d18, 0x3365b }, { 0x46d19, 0x335b1 }, { 0x46d1a, 0x3365c },
{ 0x46d1b, 0x3365d }, { 0x46d1c, 0x3365e }, { 0x46d1d, 0x3365f },
{ 0x46d1e, 0x33660 }, { 0x46d1f, 0x33661 }, { 0x46d20, 0x33662 },
{ 0x46d21, 0x33663 }, { 0x46d22, 0x335a9 }, { 0x46d23, 0x335aa },
{ 0x46d24, 0x335b2 }, { 0x46d25, 0x335ed }, { 0x46d26, 0x335ee },
{ 0x46d27, 0x335ef }, { 0x46d28, 0x335f0 }, { 0x46d29, 0x335f1 },
{ 0x46d2a, 0x335f2 }, { 0x46d2b, 0x335f4 }, { 0x46d2c, 0x335f5 },
{ 0x46d2d, 0x335f6 }, { 0x46d2e, 0x335f7 }, { 0x46d2f, 0x335b4 },
{ 0x46d30, 0x335f8 }, { 0x46d31, 0x335f9 }, { 0x46d32, 0x335fa },
{ 0x46d33, 0x335fb }, { 0x46d34, 0x335fc }, { 0x46d35, 0x335fd },
{ 0x46d36, 0x335ff }, { 0x46d37, 0x33600 }, { 0x46d38, 0x33601 },
{ 0x46d39, 0x33602 }, { 0x46d3a, 0x3380f }, { 0x46d3b, 0x33695 },
{ 0x46d47, 0x07536 }, { 0x46d4a, 0x3360c }, { 0x46d4e, 0x337fc },
{ 0x46d50, 0x337fd }, { 0x46d56, 0x33800 }, { 0x46d58, 0x33694 },
{ 0x46dc2, 0x337f3 }, { 0x46dc6, 0x337fb }, { 0x46dc7, 0x337f9 },
{ 0x46dca, 0x33802 }, { 0x46dd3, 0x33775 }
};
#define MAITRED_COUNT_DE 105
static const TagMapping MAITRED_MAP_DE[105] = {
{ 0x46cd0, 0x3f94c }, { 0x46ce2, 0x3f9a6 }, { 0x46ced, 0x3f9a7 },
{ 0x46cf8, 0x3f9a8 }, { 0x46d03, 0x3f9a9 }, { 0x46d0e, 0x3f9aa },
{ 0x46d19, 0x3f9ab }, { 0x46d24, 0x3f9ac }, { 0x46d2f, 0x3f9ad },
{ 0x46cd1, 0x3f9ae }, { 0x46cd9, 0x3f9af }, { 0x46cda, 0x3f9b0 },
{ 0x46cdb, 0x3f9b1 }, { 0x46cdc, 0x3f9b2 }, { 0x46cdd, 0x3f9b3 },
{ 0x46cde, 0x3f9b4 }, { 0x46cdf, 0x3f9b5 }, { 0x46ce0, 0x3f9b6 },
{ 0x46ce1, 0x3f9b7 }, { 0x46ce3, 0x3f9b8 }, { 0x46ce4, 0x3f9b9 },
{ 0x46ce5, 0x3f9ba }, { 0x46ce6, 0x3f9bb }, { 0x46ce7, 0x3f9bc },
{ 0x46ce8, 0x3f9bd }, { 0x46ce9, 0x3f9be }, { 0x46cea, 0x3f9bf },
{ 0x46ceb, 0x3f9c0 }, { 0x46cec, 0x3f9c1 }, { 0x46cee, 0x3f9c2 },
{ 0x46cef, 0x3f9c3 }, { 0x46cf0, 0x3f9c4 }, { 0x46cf1, 0x3f9c5 },
{ 0x46cf5, 0x3f9c9 }, { 0x46cf6, 0x3f9ca }, { 0x46cf7, 0x3f9cb },
{ 0x46cf9, 0x3f9cc }, { 0x46cfa, 0x3f9cd }, { 0x46cfb, 0x3f9ce },
{ 0x46cfc, 0x3f9cf }, { 0x46cfd, 0x3f9d0 }, { 0x46cfe, 0x3f9d1 },
{ 0x46cff, 0x3f9d2 }, { 0x46d00, 0x3f9d3 }, { 0x46d01, 0x3f9d4 },
{ 0x46d02, 0x3f9d5 }, { 0x46d04, 0x3f9d6 }, { 0x46d05, 0x3f9d7 },
{ 0x46d06, 0x3f9d9 }, { 0x46d07, 0x3f9da }, { 0x46d08, 0x3f9db },
{ 0x46d09, 0x3f98a }, { 0x46d0a, 0x3f98b }, { 0x46d0b, 0x3f98c },
{ 0x46d0c, 0x3f98d }, { 0x46d0d, 0x3f98e }, { 0x46d0f, 0x3f98f },
{ 0x46d10, 0x3f991 }, { 0x46d11, 0x3f992 }, { 0x46d12, 0x3f993 },
{ 0x46d13, 0x3f994 }, { 0x46d14, 0x3f996 }, { 0x46d15, 0x3f997 },
{ 0x46d16, 0x3f998 }, { 0x46d17, 0x3f999 }, { 0x46d18, 0x3f99a },
{ 0x46d1a, 0x3f99b }, { 0x46d1b, 0x3f99c }, { 0x46d1c, 0x3f99d },
{ 0x46d1d, 0x3f99e }, { 0x46d1e, 0x3f99f }, { 0x46d1f, 0x3f9a1 },
{ 0x46d20, 0x3f9a2 }, { 0x46d21, 0x3f9a3 }, { 0x46d22, 0x3f9a4 },
{ 0x46d23, 0x3f9a5 }, { 0x46d25, 0x3f9dd }, { 0x46d26, 0x3f9de },
{ 0x46d27, 0x3f9df }, { 0x46d28, 0x3f9e0 }, { 0x46d29, 0x3f9e1 },
{ 0x46d2a, 0x3f9e2 }, { 0x46d2b, 0x3f9e3 }, { 0x46d2c, 0x3f9e4 },
{ 0x46d2d, 0x3f9e5 }, { 0x46d2e, 0x3f9e6 }, { 0x46d30, 0x3f9e7 },
{ 0x46d31, 0x3f9e8 }, { 0x46d32, 0x3f9e9 }, { 0x46d33, 0x3f9ea },
{ 0x46d34, 0x3f9eb }, { 0x46d35, 0x3f9ec }, { 0x46d36, 0x3f9ed },
{ 0x46d37, 0x3f9ee }, { 0x46d38, 0x3f9ef }, { 0x46d39, 0x3f9f0 },
{ 0x46cd2, 0x3f9f1 }, { 0x46cd3, 0x3f9f2 }, { 0x46cd4, 0x3f9f3 },
{ 0x46cd5, 0x3f9f9 }, { 0x46cd6, 0x3f9fa }, { 0x46cd7, 0x3f9fb },
{ 0x46cd8, 0x3f9fc }, { 0x46d3b, 0x3f853 }, { 0x46d58, 0x3f83c }
};
void writeTagMappings(const char *name, const TagMapping *map, int count) {
outputFile->seek(dataOffset);
for (int idx = 0; idx < count; ++idx, ++map) {
outputFile->writeLong(map->_src);
outputFile->writeLong(map->_dest);
}
uint size = outputFile->size() - dataOffset;
writeEntryHeader(name, dataOffset, size);
dataOffset += size;
}
void writeAllTagMappings() {
writeTagMappings("TagMap/Barbot", BARBOT_MAP_EN, BARBOT_COUNT_EN);
writeTagMappings("TagMap/Bellbot", BELLBOT_MAP_EN, BELLBOT_COUNT_EN);
writeTagMappings("TagMap/Deskbot", DESKBOT_MAP_EN, DESKBOT_COUNT_EN);
writeTagMappings("TagMap/Doorbot", DOORBOT_MAP_EN, DOORBOT_COUNT_EN);
writeTagMappings("TagMap/Liftbot", LIFTBOT_MAP_EN, LIFTBOT_COUNT_EN);
writeTagMappings("TagMap/MaitreD", MAITRED_MAP_EN, MAITRED_COUNT_EN);
writeTagMappings("TagMap/Barbot/DE", BARBOT_MAP_DE, BARBOT_COUNT_DE);
writeTagMappings("TagMap/Bellbot/DE", BELLBOT_MAP_DE, BELLBOT_COUNT_DE);
writeTagMappings("TagMap/Deskbot/DE", DESKBOT_MAP_DE, DESKBOT_COUNT_DE);
writeTagMappings("TagMap/Doorbot/DE", DOORBOT_MAP_DE, DOORBOT_COUNT_DE);
writeTagMappings("TagMap/Liftbot/DE", LIFTBOT_MAP_DE, LIFTBOT_COUNT_DE);
writeTagMappings("TagMap/MaitreD/DE", MAITRED_MAP_DE, MAITRED_COUNT_DE);
}

View File

@@ -0,0 +1,36 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COMMON_TAG_MAPS_H
#define COMMON_TAG_MAPS_H
#include "common/scummsys.h"
struct TagMapping {
uint _src;
uint _dest;
};
extern void writeAllTagMappings();
extern void writeEntryHeader(const char *name, uint offset, uint size);
extern uint dataOffset;
#endif

View File

@@ -0,0 +1,96 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "common/str.h"
#include "winexe.h"
namespace Common {
WinResourceID &WinResourceID::operator=(const String &x) {
_name = x;
_idType = kIDTypeString;
return *this;
}
WinResourceID &WinResourceID::operator=(uint32 x) {
_id = x;
_idType = kIDTypeNumerical;
return *this;
}
bool WinResourceID::operator==(const String &x) const {
return _idType == kIDTypeString && _name.equalsIgnoreCase(x);
}
bool WinResourceID::operator==(const uint32 &x) const {
return _idType == kIDTypeNumerical && _id == x;
}
bool WinResourceID::operator==(const WinResourceID &x) const {
if (_idType != x._idType)
return false;
if (_idType == kIDTypeString)
return _name.equalsIgnoreCase(x._name);
if (_idType == kIDTypeNumerical)
return _id == x._id;
return true;
}
String WinResourceID::getString() const {
if (_idType != kIDTypeString)
return "";
return _name;
}
uint32 WinResourceID::getID() const {
if (_idType != kIDTypeNumerical)
return 0xffffffff;
return _id;
}
String WinResourceID::toString() const {
if (_idType == kIDTypeString)
return _name;
else if (_idType == kIDTypeNumerical)
return String::format("0x%08x", _id);
return "";
}
bool WinResources::loadFromEXE(const String &fileName) {
if (fileName.empty())
return false;
File *file = new File();
if (!file->open(fileName.c_str())) {
delete file;
return false;
}
return loadFromEXE(file);
}
} // End of namespace Common

View File

@@ -0,0 +1,129 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COMMON_WINEXE_H
#define COMMON_WINEXE_H
#include "file.h"
#include "hash-str.h"
#include "common/str.h"
namespace Common {
/** The default Windows resources. */
enum WinResourceType {
kWinCursor = 0x01,
kWinBitmap = 0x02,
kWinIcon = 0x03,
kWinMenu = 0x04,
kWinDialog = 0x05,
kWinString = 0x06,
kWinFontDir = 0x07,
kWinFont = 0x08,
kWinAccelerator = 0x09,
kWinRCData = 0x0A,
kWinMessageTable = 0x0B,
kWinGroupCursor = 0x0C,
kWinGroupIcon = 0x0E,
kWinVersion = 0x10,
kWinDlgInclude = 0x11,
kWinPlugPlay = 0x13,
kWinVXD = 0x14,
kWinAniCursor = 0x15,
kWinAniIcon = 0x16,
kWinHTML = 0x17,
kWinManifest = 0x18
};
class WinResourceID {
public:
WinResourceID() { _idType = kIDTypeNull; }
WinResourceID(String x) { _idType = kIDTypeString; _name = x; }
WinResourceID(uint32 x) { _idType = kIDTypeNumerical; _id = x; }
WinResourceID &operator=(const String &x);
WinResourceID &operator=(uint32 x);
bool operator==(const String &x) const;
bool operator==(const uint32 &x) const;
bool operator==(const WinResourceID &x) const;
String getString() const;
uint32 getID() const;
String toString() const;
private:
/** An ID Type. */
enum IDType {
kIDTypeNull, ///< No type set
kIDTypeNumerical, ///< A numerical ID.
kIDTypeString ///< A string ID.
} _idType;
String _name; ///< The resource's string ID.
uint32 _id; ///< The resource's numerical ID.
};
struct WinResourceID_Hash {
uint operator()(const WinResourceID &id) const { return hashit(id.toString().c_str()); }
};
struct WinResourceID_EqualTo {
bool operator()(const WinResourceID &id1, const WinResourceID &id2) const { return id1 == id2; }
};
/**
* A class able to load resources from a Windows Executable, such
* as cursors, bitmaps, and sounds.
*/
class WinResources {
public:
virtual ~WinResources() {}
/** Clear all information. */
virtual void clear() = 0;
/** Load from an EXE file. */
virtual bool loadFromEXE(const String &fileName);
virtual bool loadFromEXE(File *stream) = 0;
/** Return a list of IDs for a given type. */
virtual const Array<WinResourceID> getIDList(const WinResourceID &type) const = 0;
/** Return a list of languages for a given type and ID. */
virtual const Array<WinResourceID> getLangList(const WinResourceID &type, const WinResourceID &id) const {
Array<WinResourceID> array;
return array;
};
/** Return a stream to the specified resource, taking the first language found (or 0 if non-existent). */
virtual File *getResource(const WinResourceID &type, const WinResourceID &id) = 0;
/** Return a stream to the specified resource (or 0 if non-existent). */
virtual File *getResource(const WinResourceID &type, const WinResourceID &id, const WinResourceID &lang) {
return getResource(type, id);
}
};
} // End of namespace Common
#endif

View File

@@ -0,0 +1,245 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "file.h"
#include "common/str.h"
#include "winexe_pe.h"
#include "common/array.h"
#include "common/endian.h"
namespace Common {
PEResources::PEResources() {
_exe = nullptr;
}
PEResources::~PEResources() {
clear();
}
void PEResources::clear() {
_sections.clear();
_resources.clear();
delete _exe; _exe = nullptr;
}
bool PEResources::loadFromEXE(File *stream) {
clear();
if (!stream)
return false;
if (stream->readUint16BE() != MKTAG16('M', 'Z'))
return false;
stream->skip(58);
uint32 peOffset = stream->readUint32LE();
if (!peOffset || peOffset >= (uint32)stream->size())
return false;
stream->seek(peOffset);
if (stream->readUint32BE() != MKTAG('P','E',0,0))
return false;
stream->skip(2);
uint16 sectionCount = stream->readUint16LE();
stream->skip(12);
uint16 optionalHeaderSize = stream->readUint16LE();
stream->skip(optionalHeaderSize + 2);
// Read in all the sections
for (uint16 i = 0; i < sectionCount; i++) {
char sectionName[9];
stream->read(sectionName, 8);
sectionName[8] = 0;
Section section;
stream->skip(4);
section.virtualAddress = stream->readUint32LE();
section.size = stream->readUint32LE();
section.offset = stream->readUint32LE();
stream->skip(16);
_sections[sectionName] = section;
}
// Currently, we require loading a resource section
if (!_sections.contains(".rsrc")) {
clear();
return false;
}
_exe = stream;
Section &resSection = _sections[".rsrc"];
parseResourceLevel(resSection, resSection.offset, 0);
return true;
}
void PEResources::parseResourceLevel(Section &section, uint32 offset, int level) {
_exe->seek(offset + 12);
uint16 namedEntryCount = _exe->readUint16LE();
uint16 intEntryCount = _exe->readUint16LE();
for (uint32 i = 0; i < (uint32)(namedEntryCount + intEntryCount); i++) {
uint32 value = _exe->readUint32LE();
WinResourceID id;
if (value & 0x80000000) {
value &= 0x7fffffff;
uint32 startPos = _exe->pos();
_exe->seek(section.offset + (value & 0x7fffffff));
// Read in the name, truncating from unicode to ascii
String name;
uint16 nameLength = _exe->readUint16LE();
while (nameLength--)
name += (char)(_exe->readUint16LE() & 0xff);
_exe->seek(startPos);
id = name;
} else {
id = value;
}
uint32 nextOffset = _exe->readUint32LE();
uint32 lastOffset = _exe->pos();
if (level == 0)
_curType = id;
else if (level == 1)
_curID = id;
else if (level == 2)
_curLang = id;
if (level < 2) {
// Time to dive down further
parseResourceLevel(section, section.offset + (nextOffset & 0x7fffffff), level + 1);
} else {
_exe->seek(section.offset + nextOffset);
Resource resource;
resource.offset = _exe->readUint32LE() + section.offset - section.virtualAddress;
resource.size = _exe->readUint32LE();
_resources[_curType][_curID][_curLang] = resource;
}
_exe->seek(lastOffset);
}
}
const Array<WinResourceID> PEResources::getTypeList() const {
Array<WinResourceID> array;
if (!_exe)
return array;
for (TypeMap::const_iterator it = _resources.begin(); it != _resources.end(); it++)
array.push_back(it->_key);
return array;
}
const Array<WinResourceID> PEResources::getIDList(const WinResourceID &type) const {
Array<WinResourceID> array;
if (!_exe || !_resources.contains(type))
return array;
const IDMap &idMap = _resources[type];
for (IDMap::const_iterator it = idMap.begin(); it != idMap.end(); it++)
array.push_back(it->_key);
return array;
}
const Array<WinResourceID> PEResources::getLangList(const WinResourceID &type, const WinResourceID &id) const {
Array<WinResourceID> array;
if (!_exe || !_resources.contains(type))
return array;
const IDMap &idMap = _resources[type];
if (!idMap.contains(id))
return array;
const LangMap &langMap = idMap[id];
for (LangMap::const_iterator it = langMap.begin(); it != langMap.end(); it++)
array.push_back(it->_key);
return array;
}
File *PEResources::getResource(const WinResourceID &type, const WinResourceID &id) {
Array<WinResourceID> langList = getLangList(type, id);
if (langList.empty())
return nullptr;
const Resource &resource = _resources[type][id][langList[0]];
byte *data = (byte *)malloc(resource.size);
_exe->seek(resource.offset);
_exe->read(data, resource.size);
File *file = new File();
file->open(data, resource.size);
return file;
}
File *PEResources::getResource(const WinResourceID &type, const WinResourceID &id, const WinResourceID &lang) {
if (!_exe || !_resources.contains(type))
return nullptr;
const IDMap &idMap = _resources[type];
if (!idMap.contains(id))
return nullptr;
const LangMap &langMap = idMap[id];
if (!langMap.contains(lang))
return nullptr;
const Resource &resource = langMap[lang];
byte *data = (byte *)malloc(resource.size);
_exe->seek(resource.offset);
_exe->read(data, resource.size);
File *file = new File();
file->open(data, resource.size);
return file;
}
} // End of namespace Common

View File

@@ -0,0 +1,98 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COMMON_WINEXE_PE_H
#define COMMON_WINEXE_PE_H
#include "file.h"
#include "hash-str.h"
#include "hashmap.h"
#include "common/str.h"
#include "winexe.h"
namespace Common {
template<class T> class Array;
class SeekableReadStream;
/**
* A class able to load resources from a Windows Portable Executable, such
* as cursors, bitmaps, and sounds.
*/
class PEResources : WinResources {
public:
PEResources();
~PEResources();
/** Clear all information. */
void clear();
/** Load from an EXE file. */
using WinResources::loadFromEXE;
bool loadFromEXE(File *stream);
/** Return a list of resource types. */
const Array<WinResourceID> getTypeList() const;
/** Return a list of IDs for a given type. */
const Array<WinResourceID> getIDList(const WinResourceID &type) const;
/** Return a list of languages for a given type and ID. */
const Array<WinResourceID> getLangList(const WinResourceID &type, const WinResourceID &id) const;
/** Return a stream to the specified resource, taking the first language found (or 0 if non-existent). */
File *getResource(const WinResourceID &type, const WinResourceID &id);
/** Return a stream to the specified resource (or 0 if non-existent). */
File *getResource(const WinResourceID &type, const WinResourceID &id, const WinResourceID &lang);
/** Returns true if the resources is empty */
bool empty() const { return _sections.empty(); }
private:
struct Section {
uint32 virtualAddress;
uint32 size;
uint32 offset;
};
HashMap<String, Section, IgnoreCase_Hash, IgnoreCase_EqualTo> _sections;
File *_exe;
void parseResourceLevel(Section &section, uint32 offset, int level);
WinResourceID _curType, _curID, _curLang;
struct Resource {
uint32 offset;
uint32 size;
};
typedef HashMap<WinResourceID, Resource, WinResourceID_Hash, WinResourceID_EqualTo> LangMap;
typedef HashMap<WinResourceID, LangMap, WinResourceID_Hash, WinResourceID_EqualTo> IDMap;
typedef HashMap<WinResourceID, IDMap, WinResourceID_Hash, WinResourceID_EqualTo> TypeMap;
TypeMap _resources;
};
} // End of namespace Common
#endif

View File

@@ -0,0 +1,455 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Disable symbol overrides so that we can use zlib.h
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#define USE_ZLIB
#include "zlib.h"
#include "common/ptr.h"
#include "common/util.h"
#include "common/stream.h"
#if defined(USE_ZLIB)
#include <zlib.h>
#if ZLIB_VERNUM < 0x1204
#error Version 1.2.0.4 or newer of zlib is required for this code
#endif
#endif
namespace Common {
/**
* Stubs for ScummVM stuff I don't want to have to link in
*/
void debug(int level, const char *s, ...) {}
char *SeekableReadStream::readLine(char *buf, size_t bufSize, bool handleCR) {
return nullptr;
}
String SeekableReadStream::readLine(bool handleCR) {
return String();
}
#if defined(USE_ZLIB)
bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long srcLen) {
return Z_OK == ::uncompress(dst, dstLen, src, srcLen);
}
bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen, const byte *dict, uint dictLen) {
if (!dst || !dstLen || !src || !srcLen)
return false;
// Initialize zlib
z_stream stream;
stream.next_in = const_cast<byte *>(src);
stream.avail_in = srcLen;
stream.next_out = dst;
stream.avail_out = dstLen;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
// Negative MAX_WBITS tells zlib there's no zlib header
int err = inflateInit2(&stream, -MAX_WBITS);
if (err != Z_OK)
return false;
// Set the dictionary, if provided
if (dict != nullptr) {
err = inflateSetDictionary(&stream, const_cast<byte *>(dict), dictLen);
if (err != Z_OK) {
inflateEnd(&stream);
return false;
}
}
err = inflate(&stream, Z_SYNC_FLUSH);
if (err != Z_OK && err != Z_STREAM_END) {
inflateEnd(&stream);
return false;
}
inflateEnd(&stream);
return true;
}
enum {
kTempBufSize = 65536
};
bool inflateZlibInstallShield(byte *dst, uint dstLen, const byte *src, uint srcLen) {
if (!dst || !dstLen || !src || !srcLen)
return false;
// See if we have sync bytes. If so, just use our function for that.
if (srcLen >= 4 && READ_BE_UINT32(src + srcLen - 4) == 0xFFFF)
return inflateZlibHeaderless(dst, dstLen, src, srcLen);
// Otherwise, we have some custom code we get to use here.
byte *temp = (byte *)malloc(kTempBufSize);
uint32 bytesRead = 0, bytesProcessed = 0;
while (bytesRead < srcLen) {
uint16 chunkSize = READ_LE_UINT16(src + bytesRead);
bytesRead += 2;
// Initialize zlib
z_stream stream;
stream.next_in = const_cast<byte *>(src + bytesRead);
stream.avail_in = chunkSize;
stream.next_out = temp;
stream.avail_out = kTempBufSize;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
// Negative MAX_WBITS tells zlib there's no zlib header
int err = inflateInit2(&stream, -MAX_WBITS);
if (err != Z_OK)
return false;
err = inflate(&stream, Z_FINISH);
if (err != Z_OK && err != Z_STREAM_END) {
inflateEnd(&stream);
free(temp);
return false;
}
memcpy(dst + bytesProcessed, temp, stream.total_out);
bytesProcessed += stream.total_out;
inflateEnd(&stream);
bytesRead += chunkSize;
}
free(temp);
return true;
}
#ifndef RELEASE_BUILD
static bool _shownBackwardSeekingWarning = false;
#endif
/**
* A simple wrapper class which can be used to wrap around an arbitrary
* other SeekableReadStream and will then provide on-the-fly decompression support.
* Assumes the compressed data to be in gzip format.
*/
class GZipReadStream : public SeekableReadStream {
protected:
enum {
BUFSIZE = 16384 // 1 << MAX_WBITS
};
byte _buf[BUFSIZE];
ScopedPtr<SeekableReadStream> _wrapped;
z_stream _stream;
int _zlibErr;
uint32 _pos;
uint32 _origSize;
bool _eos;
public:
GZipReadStream(SeekableReadStream *w, uint32 knownSize = 0) : _wrapped(w), _stream() {
assert(w != nullptr);
// Verify file header is correct
w->seek(0, SEEK_SET);
uint16 header = w->readUint16BE();
assert(header == 0x1F8B ||
((header & 0x0F00) == 0x0800 && header % 31 == 0));
if (header == 0x1F8B) {
// Retrieve the original file size
w->seek(-4, SEEK_END);
_origSize = w->readUint32LE();
} else {
// Original size not available in zlib format
// use an otherwise known size if supplied.
_origSize = knownSize;
}
_pos = 0;
w->seek(0, SEEK_SET);
_eos = false;
// Adding 32 to windowBits indicates to zlib that it is supposed to
// automatically detect whether gzip or zlib headers are used for
// the compressed file. This feature was added in zlib 1.2.0.4,
// released 10 August 2003.
// Note: This is *crucial* for savegame compatibility, do *not* remove!
_zlibErr = inflateInit2(&_stream, MAX_WBITS + 32);
if (_zlibErr != Z_OK)
return;
// Setup input buffer
_stream.next_in = _buf;
_stream.avail_in = 0;
}
~GZipReadStream() {
inflateEnd(&_stream);
}
bool err() const override { return (_zlibErr != Z_OK) && (_zlibErr != Z_STREAM_END); }
void clearErr() override {
// only reset _eos; I/O errors are not recoverable
_eos = false;
}
uint32 read(void *dataPtr, uint32 dataSize) override {
_stream.next_out = (byte *)dataPtr;
_stream.avail_out = dataSize;
// Keep going while we get no error
while (_zlibErr == Z_OK && _stream.avail_out) {
if (_stream.avail_in == 0 && !_wrapped->eos()) {
// If we are out of input data: Read more data, if available.
_stream.next_in = _buf;
_stream.avail_in = _wrapped->read(_buf, BUFSIZE);
}
_zlibErr = inflate(&_stream, Z_NO_FLUSH);
}
// Update the position counter
_pos += dataSize - _stream.avail_out;
if (_zlibErr == Z_STREAM_END && _stream.avail_out > 0)
_eos = true;
return dataSize - _stream.avail_out;
}
bool eos() const override {
return _eos;
}
int64 pos() const override {
return _pos;
}
int64 size() const override {
return _origSize;
}
bool seek(int64 offset, int whence = SEEK_SET) override {
int32 newPos = 0;
switch (whence) {
default:
// fallthrough intended
case SEEK_SET:
newPos = offset;
break;
case SEEK_CUR:
newPos = _pos + offset;
break;
case SEEK_END:
// NOTE: This can be an expensive operation (see below).
newPos = size() + offset;
break;
}
assert(newPos >= 0);
if ((uint32)newPos < _pos) {
// To search backward, we have to restart the whole decompression
// from the start of the file. A rather wasteful operation, best
// to avoid it. :/
#ifndef RELEASE_BUILD
if (!_shownBackwardSeekingWarning) {
// We only throw this warning once per stream, to avoid
// getting the console swarmed with warnings when consecutive
// seeks are made.
debug(1, "Backward seeking in GZipReadStream detected");
_shownBackwardSeekingWarning = true;
}
#endif
_pos = 0;
_wrapped->seek(0, SEEK_SET);
_zlibErr = inflateReset(&_stream);
if (_zlibErr != Z_OK)
return false; // FIXME: STREAM REWRITE
_stream.next_in = _buf;
_stream.avail_in = 0;
}
offset = newPos - _pos;
// Skip the given amount of data (very inefficient if one tries to skip
// huge amounts of data, but usually client code will only skip a few
// bytes, so this should be fine.
byte tmpBuf[1024];
while (!err() && offset > 0) {
offset -= read(tmpBuf, MIN((int32)sizeof(tmpBuf), (int32)offset));
}
_eos = false;
return true; // FIXME: STREAM REWRITE
}
};
/**
* A simple wrapper class which can be used to wrap around an arbitrary
* other WriteStream and will then provide on-the-fly compression support.
* The compressed data is written in the gzip format.
*/
class GZipWriteStream : public WriteStream {
protected:
enum {
BUFSIZE = 16384 // 1 << MAX_WBITS
};
byte _buf[BUFSIZE];
ScopedPtr<WriteStream> _wrapped;
z_stream _stream;
int _zlibErr;
uint32 _pos;
void processData(int flushType) {
// This function is called by both write() and finalize().
while (_zlibErr == Z_OK && (_stream.avail_in || flushType == Z_FINISH)) {
if (_stream.avail_out == 0) {
if (_wrapped->write(_buf, BUFSIZE) != BUFSIZE) {
_zlibErr = Z_ERRNO;
break;
}
_stream.next_out = _buf;
_stream.avail_out = BUFSIZE;
}
_zlibErr = deflate(&_stream, flushType);
}
}
public:
GZipWriteStream(WriteStream *w) : _wrapped(w), _stream(), _pos(0) {
assert(w != nullptr);
// Adding 16 to windowBits indicates to zlib that it is supposed to
// write gzip headers. This feature was added in zlib 1.2.0.4,
// released 10 August 2003.
// Note: This is *crucial* for savegame compatibility, do *not* remove!
_zlibErr = deflateInit2(&_stream,
Z_DEFAULT_COMPRESSION,
Z_DEFLATED,
MAX_WBITS + 16,
8,
Z_DEFAULT_STRATEGY);
assert(_zlibErr == Z_OK);
_stream.next_out = _buf;
_stream.avail_out = BUFSIZE;
_stream.avail_in = 0;
_stream.next_in = nullptr;
}
~GZipWriteStream() {
finalize();
deflateEnd(&_stream);
}
bool err() const override {
// CHECKME: does Z_STREAM_END make sense here?
return (_zlibErr != Z_OK && _zlibErr != Z_STREAM_END) || _wrapped->err();
}
void clearErr() override {
// Note: we don't reset the _zlibErr here, as it is not
// clear in general how
_wrapped->clearErr();
}
void finalize() override {
if (_zlibErr != Z_OK)
return;
// Process whatever remaining data there is.
processData(Z_FINISH);
// Since processData only writes out blocks of size BUFSIZE,
// we may have to flush some stragglers.
uint remainder = BUFSIZE - _stream.avail_out;
if (remainder > 0) {
if (_wrapped->write(_buf, remainder) != remainder) {
_zlibErr = Z_ERRNO;
}
}
// Finalize the wrapped savefile, too
_wrapped->finalize();
}
uint32 write(const void *dataPtr, uint32 dataSize) override {
if (err())
return 0;
// Hook in the new data ...
// Note: We need to make a const_cast here, as zlib is not aware
// of the const keyword.
_stream.next_in = const_cast<byte *>((const byte *)dataPtr);
_stream.avail_in = dataSize;
// ... and flush it to disk
processData(Z_NO_FLUSH);
_pos += dataSize - _stream.avail_in;
return dataSize - _stream.avail_in;
}
int64 pos() const override { return _pos; }
};
#endif // USE_ZLIB
SeekableReadStream *wrapCompressedReadStream(SeekableReadStream *toBeWrapped, uint32 knownSize) {
if (toBeWrapped) {
uint16 header = toBeWrapped->readUint16BE();
bool isCompressed = (header == 0x1F8B ||
((header & 0x0F00) == 0x0800 &&
header % 31 == 0));
toBeWrapped->seek(-2, SEEK_CUR);
if (isCompressed) {
#if defined(USE_ZLIB)
return new GZipReadStream(toBeWrapped, knownSize);
#else
delete toBeWrapped;
return NULL;
#endif
}
}
return toBeWrapped;
}
WriteStream *wrapCompressedWriteStream(WriteStream *toBeWrapped) {
#if defined(USE_ZLIB)
if (toBeWrapped)
return new GZipWriteStream(toBeWrapped);
#endif
return toBeWrapped;
}
} // End of namespace Common

View File

@@ -0,0 +1,135 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef COMMON_ZLIB_H
#define COMMON_ZLIB_H
#include "common/scummsys.h"
namespace Common {
class SeekableReadStream;
class WriteStream;
#if defined(USE_ZLIB)
/**
* Thin wrapper around zlib's uncompress() function. This wrapper makes
* it possible to uncompress data in engines without being forced to link
* them against zlib, thus simplifying the build system.
*
* Taken from the zlib manual:
* Decompresses the src buffer into the dst buffer.
* srcLen is the byte length of the source buffer. Upon entry, dstLen is the
* total size of the destination buffer, which must be large enough to hold
* the entire uncompressed data. Upon exit, dstLen is the actual size of the
* compressed buffer.
*
* @param dst the buffer to store into.
* @param dstLen a pointer to the size of the destination buffer.
* @param src the data to be decompressed.
* @param srcLen the size of the compressed data.
*
* @return true on success (i.e. Z_OK), false otherwise.
*/
bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long srcLen);
/**
* Wrapper around zlib's inflate functions. This function will call the
* necessary inflate functions to uncompress data compressed with deflate
* but *not* with the standard zlib header.
*
* Decompresses the src buffer into the dst buffer.
* srcLen is the byte length of the source buffer, dstLen is the byte
* length of the output buffer.
* It decompress as much data as possible, up to dstLen bytes.
* If a dictionary is provided through the dict buffer, uses it to initializes
* the internal decompression dictionary, before the decompression takes place.
*
* @param dst the buffer to store into.
* @param dstLen the size of the destination buffer.
* @param src the data to be decompressed.
* @param srcLen the size of the compressed data.
* @param dict (optional) a decompress dictionary.
* @param dictLen (optional) the size of the dictionary.
* Mandatory if dict is not 0.
*
* @return true on success (Z_OK or Z_STREAM_END), false otherwise.
*/
bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen, const byte *dict = 0, uint dictLen = 0);
/**
* Wrapper around zlib's inflate functions. This function will call the
* necessary inflate functions to uncompress data compressed for InstallShield
* cabinet files.
*
* Decompresses the src buffer into the dst buffer.
* srcLen is the byte length of the source buffer, dstLen is the byte
* length of the output buffer.
* It decompress as much data as possible, up to dstLen bytes.
*
* @param dst the buffer to store into.
* @param dstLen the size of the destination buffer.
* @param src the data to be decompressed.
* @param srcLen the size of the compressed data.
*
* @return true on success (Z_OK or Z_STREAM_END), false otherwise.
*/
bool inflateZlibInstallShield(byte *dst, uint dstLen, const byte *src, uint srcLen);
#endif
/**
* Take an arbitrary SeekableReadStream and wrap it in a custom stream which
* provides transparent on-the-fly decompression. Assumes the data it
* retrieves from the wrapped stream to be either uncompressed or in gzip
* format. In the former case, the original stream is returned unmodified
* (and in particular, not wrapped). In the latter case the stream is
* returned wrapped, unless there is no ZLIB support, then NULL is returned
* and the old stream is destroyed.
*
* Certain GZip-formats don't supply an easily readable length, if you
* still need the length carried along with the stream, and you know
* the decompressed length at wrap-time, then it can be supplied as knownSize
* here. knownSize will be ignored if the GZip-stream DOES include a length.
*
* It is safe to call this with a NULL parameter (in this case, NULL is
* returned).
*
* @param toBeWrapped the stream to be wrapped (if it is in gzip-format)
* @param knownSize a supplied length of the compressed data (if not available directly)
*/
SeekableReadStream *wrapCompressedReadStream(SeekableReadStream *toBeWrapped, uint32 knownSize = 0);
/**
* Take an arbitrary WriteStream and wrap it in a custom stream which provides
* transparent on-the-fly compression. The compressed data is written in the
* gzip format, unless ZLIB support has been disabled, in which case the given
* stream is returned unmodified (and in particular, not wrapped).
*
* It is safe to call this with a NULL parameter (in this case, NULL is
* returned).
*/
WriteStream *wrapCompressedWriteStream(WriteStream *toBeWrapped);
} // End of namespace Common
#endif