diff options
author | Greg Frieger | 2009-03-07 04:49:34 +0000 |
---|---|---|
committer | Greg Frieger | 2009-03-07 04:49:34 +0000 |
commit | f1dd168aae21d3139d47f3e121e1b09731a42f36 (patch) | |
tree | 50bc10d7fee5fd62e4fe9692b0312f5ca756833b /engines/sci/scicore | |
parent | 7fe1dbdf16be645f0ea0ccf0859ea3a4303181f4 (diff) | |
download | scummvm-rg350-f1dd168aae21d3139d47f3e121e1b09731a42f36.tar.gz scummvm-rg350-f1dd168aae21d3139d47f3e121e1b09731a42f36.tar.bz2 scummvm-rg350-f1dd168aae21d3139d47f3e121e1b09731a42f36.zip |
Merged scicore/resource_map.cpp and scicore/resource_patch.cpp to scicore/resource.cpp because these remaining functions are members of ResourceManager
svn-id: r39172
Diffstat (limited to 'engines/sci/scicore')
-rw-r--r-- | engines/sci/scicore/resource.cpp | 191 | ||||
-rw-r--r-- | engines/sci/scicore/resource.h | 3 | ||||
-rw-r--r-- | engines/sci/scicore/resource_map.cpp | 135 | ||||
-rw-r--r-- | engines/sci/scicore/resource_patch.cpp | 129 |
4 files changed, 194 insertions, 264 deletions
diff --git a/engines/sci/scicore/resource.cpp b/engines/sci/scicore/resource.cpp index aca8e23592..389216e9d2 100644 --- a/engines/sci/scicore/resource.cpp +++ b/engines/sci/scicore/resource.cpp @@ -36,6 +36,7 @@ namespace Sci { #undef SCI_REQUIRE_RESOURCE_FILES + //#define SCI_VERBOSE_RESMGR 1 const char *sci_version_types[] = { @@ -723,4 +724,194 @@ int ResourceManager::detectVolVersion() { return SCI_VERSION_1_1; } +// version-agnostic patch application +void ResourceManager::processPatch(ResourceSource *source, + const char *filename, ResourceType restype, int resnumber) { + Common::File file; + Resource *newrsc; + uint32 resId = RESOURCE_HASH(restype, resnumber); + byte patchtype, patch_data_offset; + int fsize; + + if (resnumber == -1) + return; + if (!file.open(filename)) { + perror("""__FILE__"": (""__LINE__""): failed to open"); + return; + } + fsize = file.size(); + if (fsize < 3) { + debug("Patching %s failed - file too small", filename); + return; + } + + patchtype = file.readByte() & 0x7F; + patch_data_offset = file.readByte(); + + if (patchtype != restype) { + debug("Patching %s failed - resource type mismatch", filename); + return; + } + if (patch_data_offset + 2 >= fsize) { + debug("Patching %s failed - patch starting at offset %d can't be in file of size %d", + filename, patch_data_offset + 2, fsize); + return; + } + // Prepare destination, if neccessary + if (_resMap.contains(resId) == false) { + newrsc = new Resource; + _resMap.setVal(resId, newrsc); + } else + newrsc = _resMap.getVal(resId); + // Overwrite everything, because we're patching + newrsc->id = resId; + newrsc->number = resnumber; + newrsc->status = SCI_STATUS_NOMALLOC; + newrsc->type = restype; + newrsc->source = source; + newrsc->size = fsize - patch_data_offset - 2; + newrsc->file_offset = 2 + patch_data_offset; + debug("Patching %s - OK", filename); +} + + +void ResourceManager::readResourcePatches(ResourceSource *source) { +// Note: since some SCI1 games(KQ5 floppy, SQ4) might use SCI0 naming scheme for patch files +// this function tries to read patch file with any supported naming scheme, +// regardless of _sciVersion value + + Common::String mask, name; + Common::ArchiveMemberList files; + int number; + const char *szResType; + ResourceSource *psrcPatch; + + for (int i = kResourceTypeView; i < kResourceTypeInvalid; i ++) { + files.clear(); + szResType = getResourceTypeName((ResourceType)i); + // SCI0 naming - type.nnn + mask = szResType; + mask += ".???"; + SearchMan.listMatchingMembers(files, mask); + // SCI1 and later naming - nnn.typ + mask = "*."; + mask += getResourceTypeSuffix((ResourceType)i); + SearchMan.listMatchingMembers(files, mask); + for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); x++) { + number = -1; + name = (*x)->getName(); + if (isdigit(name[0])) { + // SCI1 scheme + number = atoi(name.c_str()); + } else { + // SCI0 scheme + int resname_len = strlen(szResType); + if (scumm_strnicmp(name.c_str(), szResType, resname_len) == 0) { + number = atoi(name.c_str() + resname_len + 1); + } + } + psrcPatch = new ResourceSource; + psrcPatch->source_type = kSourcePatch; + psrcPatch->location_name = name; + processPatch(psrcPatch, name.c_str(), (ResourceType)i, number); + } + } +} + +int ResourceManager::readResourceMapSCI0(ResourceSource *map) { + Common::File file; + Resource *res; + ResourceType type; + uint16 number, id; + uint32 offset; + + if (!file.open(map->location_name)) + return SCI_ERROR_RESMAP_NOT_FOUND; + + file.seek(0, SEEK_SET); + + byte bMask = _mapVersion == SCI_VERSION_01_VGA_ODD ? 0xF0: 0xFC; + byte bShift = _mapVersion == SCI_VERSION_01_VGA_ODD ? 28 : 26; + + do { + id = file.readUint16LE(); + offset = file.readUint32LE(); + + if (file.ioFailed()) { + warning("Error while reading %s: ", map->location_name.c_str()); + perror(""); + return SCI_ERROR_RESMAP_NOT_FOUND; + } + if(offset == 0xFFFFFFFF) + break; + + type = (ResourceType)(id >> 11); + number = id & 0x7FF; + uint32 resId = RESOURCE_HASH(type, number); + // adding a new resource + if (_resMap.contains(resId) == false) { + res = new Resource; + res->id = id; + res->file_offset = offset & (((~bMask) << 24) | 0xFFFFFF); + res->number = number; + res->type = type; + res->source = getVolume(map, offset >> bShift); + _resMap.setVal(resId, res); + } + } while (!file.eos()); + return 0; +} + +int ResourceManager::readResourceMapSCI1(ResourceSource *map, ResourceSource *vol) { + Common::File file; + Resource *res; + if (!file.open(map->location_name)) + return SCI_ERROR_RESMAP_NOT_FOUND; + + resource_index_t resMap[kResourceTypeInvalid]; + memset(resMap, 0, sizeof(resource_index_t) * kResourceTypeInvalid); + byte type = 0, prevtype = 0; + byte nEntrySize = _mapVersion == SCI_VERSION_1_1 ? SCI11_RESMAP_ENTRIES_SIZE : SCI1_RESMAP_ENTRIES_SIZE; + uint32 resId; + + // Read resource type and offsets to resource offsets block from .MAP file + // The last entry has type=0xFF (0x1F) and offset equals to map file length + do { + type = file.readByte() & 0x1F; + resMap[type].wOffset = file.readUint16LE(); + resMap[prevtype].wSize = (resMap[type].wOffset + - resMap[prevtype].wOffset) / nEntrySize; + prevtype = type; + } while (type != 0x1F); // the last entry is FF + + // reading each type's offsets + uint32 off = 0; + for (type = 0; type < kResourceTypeInvalid; type++) { + if (resMap[type].wOffset == 0) // this resource does not exist in map + continue; + file.seek(resMap[type].wOffset); + for (int i = 0; i < resMap[type].wSize; i++) { + uint16 number = file.readUint16LE(); + file.read(&off, nEntrySize - 2); + if (file.ioFailed()) { + warning("Error while reading %s: ", map->location_name.c_str()); + perror(""); + return SCI_ERROR_RESMAP_NOT_FOUND; + } + resId = RESOURCE_HASH(type, number); + // adding new resource only if it does not exist + if (_resMap.contains(resId) == false) { + res = new Resource; + _resMap.setVal(resId, res); + res->type = (ResourceType)type; + res->number = number; + res->id = res->number | (res->type << 16); + res->source = _mapVersion < SCI_VERSION_1_1 ? getVolume(map, off >> 28) : vol; + res->file_offset = _mapVersion < SCI_VERSION_1_1 ? off & 0x0FFFFFFF : off << 1; + } + } + } + return 0; +} + } // End of namespace Sci diff --git a/engines/sci/scicore/resource.h b/engines/sci/scicore/resource.h index 6550514e25..a44ff0f0fa 100644 --- a/engines/sci/scicore/resource.h +++ b/engines/sci/scicore/resource.h @@ -94,6 +94,9 @@ enum ResSourceType { #define RESSOURCE_ADDRESSING_MASK 128 #define RESOURCE_HASH(type, number) (uint32)((type<<16) | number) +#define SCI0_RESMAP_ENTRIES_SIZE 6 +#define SCI1_RESMAP_ENTRIES_SIZE 6 +#define SCI11_RESMAP_ENTRIES_SIZE 5 extern const char *sci_error_types[]; extern const char *sci_version_types[]; diff --git a/engines/sci/scicore/resource_map.cpp b/engines/sci/scicore/resource_map.cpp deleted file mode 100644 index 9279ca3b11..0000000000 --- a/engines/sci/scicore/resource_map.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci_memory.h" -#include "sci/scicore/resource.h" -#include "sci/tools.h" - -#include "common/util.h" -#include "common/file.h" - -namespace Sci { - -#define SCI0_RESMAP_ENTRIES_SIZE 6 -#define SCI1_RESMAP_ENTRIES_SIZE 6 -#define SCI11_RESMAP_ENTRIES_SIZE 5 - -int ResourceManager::readResourceMapSCI0(ResourceSource *map) { - Common::File file; - Resource *res; - ResourceType type; - uint16 number, id; - uint32 offset; - - if (!file.open(map->location_name)) - return SCI_ERROR_RESMAP_NOT_FOUND; - - file.seek(0, SEEK_SET); - - byte bMask = _mapVersion == SCI_VERSION_01_VGA_ODD ? 0xF0: 0xFC; - byte bShift = _mapVersion == SCI_VERSION_01_VGA_ODD ? 28 : 26; - - do { - id = file.readUint16LE(); - offset = file.readUint32LE(); - - if (file.ioFailed()) { - warning("Error while reading %s: ", map->location_name.c_str()); - perror(""); - return SCI_ERROR_RESMAP_NOT_FOUND; - } - if(offset == 0xFFFFFFFF) - break; - - type = (ResourceType)(id >> 11); - number = id & 0x7FF; - uint32 resId = RESOURCE_HASH(type, number); - // adding a new resource - if (_resMap.contains(resId) == false) { - res = new Resource; - res->id = id; - res->file_offset = offset & (((~bMask) << 24) | 0xFFFFFF); - res->number = number; - res->type = type; - res->source = getVolume(map, offset >> bShift); - _resMap.setVal(resId, res); - } - } while (!file.eos()); - return 0; -} - -int ResourceManager::readResourceMapSCI1(ResourceSource *map, ResourceSource *vol) { - Common::File file; - Resource *res; - if (!file.open(map->location_name)) - return SCI_ERROR_RESMAP_NOT_FOUND; - - resource_index_t resMap[kResourceTypeInvalid]; - memset(resMap, 0, sizeof(resource_index_t) * kResourceTypeInvalid); - byte type = 0, prevtype = 0; - byte nEntrySize = _mapVersion == SCI_VERSION_1_1 ? SCI11_RESMAP_ENTRIES_SIZE : SCI1_RESMAP_ENTRIES_SIZE; - uint32 resId; - - // Read resource type and offsets to resource offsets block from .MAP file - // The last entry has type=0xFF (0x1F) and offset equals to map file length - do { - type = file.readByte() & 0x1F; - resMap[type].wOffset = file.readUint16LE(); - resMap[prevtype].wSize = (resMap[type].wOffset - - resMap[prevtype].wOffset) / nEntrySize; - prevtype = type; - } while (type != 0x1F); // the last entry is FF - - // reading each type's offsets - uint32 off = 0; - for (type = 0; type < kResourceTypeInvalid; type++) { - if (resMap[type].wOffset == 0) // this resource does not exist in map - continue; - file.seek(resMap[type].wOffset); - for (int i = 0; i < resMap[type].wSize; i++) { - uint16 number = file.readUint16LE(); - file.read(&off, nEntrySize - 2); - if (file.ioFailed()) { - warning("Error while reading %s: ", map->location_name.c_str()); - perror(""); - return SCI_ERROR_RESMAP_NOT_FOUND; - } - resId = RESOURCE_HASH(type, number); - // adding new resource only if it does not exist - if (_resMap.contains(resId) == false) { - res = new Resource; - _resMap.setVal(resId, res); - res->type = (ResourceType)type; - res->number = number; - res->id = res->number | (res->type << 16); - res->source = _mapVersion < SCI_VERSION_1_1 ? getVolume(map, off >> 28) : vol; - res->file_offset = _mapVersion < SCI_VERSION_1_1 ? off & 0x0FFFFFFF : off << 1; - } - } - } - return 0; -} - -} // End of namespace Sci diff --git a/engines/sci/scicore/resource_patch.cpp b/engines/sci/scicore/resource_patch.cpp deleted file mode 100644 index 80762d9c66..0000000000 --- a/engines/sci/scicore/resource_patch.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/archive.h" -#include "common/file.h" -#include "common/debug.h" - -#include "sci/scicore/resource.h" -#include "sci/sci_memory.h" - -namespace Sci { - -// version-agnostic patch application -void ResourceManager::processPatch(ResourceSource *source, - const char *filename, ResourceType restype, int resnumber) { - Common::File file; - Resource *newrsc; - uint32 resId = RESOURCE_HASH(restype, resnumber); - byte patchtype, patch_data_offset; - int fsize; - - if (resnumber == -1) - return; - if (!file.open(filename)) { - perror("""__FILE__"": (""__LINE__""): failed to open"); - return; - } - fsize = file.size(); - if (fsize < 3) { - debug("Patching %s failed - file too small", filename); - return; - } - - patchtype = file.readByte() & 0x7F; - patch_data_offset = file.readByte(); - - if (patchtype != restype) { - debug("Patching %s failed - resource type mismatch", filename); - return; - } - if (patch_data_offset + 2 >= fsize) { - debug("Patching %s failed - patch starting at offset %d can't be in file of size %d", - filename, patch_data_offset + 2, fsize); - return; - } - // Prepare destination, if neccessary - if (_resMap.contains(resId) == false) { - newrsc = new Resource; - _resMap.setVal(resId, newrsc); - } else - newrsc = _resMap.getVal(resId); - // Overwrite everything, because we're patching - newrsc->id = resId; - newrsc->number = resnumber; - newrsc->status = SCI_STATUS_NOMALLOC; - newrsc->type = restype; - newrsc->source = source; - newrsc->size = fsize - patch_data_offset - 2; - newrsc->file_offset = 2 + patch_data_offset; - debug("Patching %s - OK", filename); -} - - -void ResourceManager::readResourcePatches(ResourceSource *source) { -// Note: since some SCI1 games(KQ5 floppy, SQ4) might use SCI0 naming scheme for patch files -// this function tries to read patch file with any supported naming scheme, -// regardless of _sciVersion value - - Common::String mask, name; - Common::ArchiveMemberList files; - int number; - const char *szResType; - ResourceSource *psrcPatch; - - for (int i = kResourceTypeView; i < kResourceTypeInvalid; i ++) { - files.clear(); - szResType = getResourceTypeName((ResourceType)i); - // SCI0 naming - type.nnn - mask = szResType; - mask += ".???"; - SearchMan.listMatchingMembers(files, mask); - // SCI1 and later naming - nnn.typ - mask = "*."; - mask += getResourceTypeSuffix((ResourceType)i); - SearchMan.listMatchingMembers(files, mask); - for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); x++) { - number = -1; - name = (*x)->getName(); - if (isdigit(name[0])) { - // SCI1 scheme - number = atoi(name.c_str()); - } else { - // SCI0 scheme - int resname_len = strlen(szResType); - if (scumm_strnicmp(name.c_str(), szResType, resname_len) == 0) { - number = atoi(name.c_str() + resname_len + 1); - } - } - psrcPatch = new ResourceSource; - psrcPatch->source_type = kSourcePatch; - psrcPatch->location_name = name; - processPatch(psrcPatch, name.c_str(), (ResourceType)i, number); - } - } -} - -} // End of namespace Sci |