Initial commit
This commit is contained in:
482
engines/kyra/resource/resource.cpp
Normal file
482
engines/kyra/resource/resource.cpp
Normal file
@@ -0,0 +1,482 @@
|
||||
/* 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 "kyra/engine/util.h"
|
||||
#include "kyra/resource/resource.h"
|
||||
#include "kyra/resource/resource_intern.h"
|
||||
|
||||
#include "common/macresman.h"
|
||||
#include "common/compression/stuffit.h"
|
||||
#include "common/concatstream.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/fs.h"
|
||||
#include "common/substream.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
Common::Archive *Resource::loadKyra1MacInstaller() {
|
||||
Common::Path kyraInstaller = Util::findMacResourceFile("Install Legend of Kyrandia");
|
||||
|
||||
if (!kyraInstaller.empty()) {
|
||||
Common::Archive *archive = loadStuffItArchive(kyraInstaller, "Install Legend of Kyrandia");
|
||||
if (!archive)
|
||||
error("Failed to load Legend of Kyrandia installer file");
|
||||
return archive;
|
||||
}
|
||||
|
||||
kyraInstaller = Util::findMacResourceFile("Legend of Kyrandia", " Installer");
|
||||
|
||||
if (!kyraInstaller.empty()) {
|
||||
Common::Array<Common::SharedPtr<Common::SeekableReadStream>> parts;
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
Common::Path partName = i == 1 ? kyraInstaller : kyraInstaller.append(Common::String::format(".%d", i));
|
||||
Common::SeekableReadStream *stream = Common::MacResManager::openFileOrDataFork(partName);
|
||||
if (!stream)
|
||||
error("Failed to load Legend of Kyrandia installer file part %s", partName.toString().c_str());
|
||||
if (stream->size() <= 100)
|
||||
error("Legend of Kyrandia installer file part %s is too short", partName.toString().c_str());
|
||||
parts.push_back(Common::SharedPtr<Common::SeekableReadStream>(new Common::SeekableSubReadStream(stream, 100, stream->size(), DisposeAfterUse::YES)));
|
||||
}
|
||||
return loadStuffItArchive(new Common::ConcatReadStream(Common::move(parts)), "Install Legend of Kyrandia", "Legend of Kyrandia(TM) Installer.*");
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Resource::Resource(KyraEngine_v1 *vm) : _archiveCache(), _files(), _archiveFiles(), _protectedFiles(), _loaders(), _vm(vm), _bigEndianPlatForm(vm->gameFlags().platform == Common::kPlatformAmiga || vm->gameFlags().platform == Common::kPlatformSegaCD) {
|
||||
initializeLoaders();
|
||||
|
||||
if (_vm->game() == GI_KYRA1 && _vm->gameFlags().platform == Common::Platform::kPlatformMacintosh)
|
||||
SearchMan.addSubDirectoryMatching(Common::FSNode(ConfMan.getPath("path")), "runtime");
|
||||
|
||||
// Initialize directories for playing from CD or with original
|
||||
// directory structure
|
||||
if (_vm->game() == GI_KYRA3)
|
||||
SearchMan.addSubDirectoryMatching(Common::FSNode(ConfMan.getPath("path")), "malcolm");
|
||||
|
||||
if (_vm->game() == GI_LOL)
|
||||
SearchMan.addSubDirectoryMatching(Common::FSNode(ConfMan.getPath("path")), "data", 0, 2);
|
||||
|
||||
_files.add("global_search", &Common::SearchManager::instance(), 3, false);
|
||||
// compressed installer archives are added at level '2',
|
||||
// but that's done in Resource::reset not here
|
||||
_files.add("protected", &_protectedFiles, 1, false);
|
||||
_files.add("archives", &_archiveFiles, 0, false);
|
||||
}
|
||||
|
||||
Resource::~Resource() {
|
||||
_loaders.clear();
|
||||
|
||||
for (ArchiveMap::iterator i = _archiveCache.begin(); i != _archiveCache.end(); ++i)
|
||||
delete i->_value;
|
||||
_archiveCache.clear();
|
||||
}
|
||||
|
||||
bool Resource::reset() {
|
||||
unloadAllPakFiles();
|
||||
|
||||
Common::FSNode dir(ConfMan.getPath("path"));
|
||||
|
||||
if (!dir.exists() || !dir.isDirectory())
|
||||
error("invalid game path '%s'", dir.getPath().toString(Common::Path::kNativeSeparator).c_str());
|
||||
|
||||
if (_vm->game() == GI_KYRA1 && _vm->gameFlags().platform == Common::kPlatformMacintosh && _vm->gameFlags().useInstallerPackage) {
|
||||
Common::Archive *archive = loadKyra1MacInstaller();
|
||||
if (!archive)
|
||||
error("Could not find Legend of Kyrandia installer file");
|
||||
|
||||
_files.add("installer", archive, 0, false);
|
||||
|
||||
Common::ArchiveMemberList members;
|
||||
archive->listMatchingMembers(members, "*.PAK");
|
||||
for (Common::ArchiveMemberList::const_iterator it = members.begin(); it != members.end(); ++it) {
|
||||
Common::String name = (*it)->getName();
|
||||
Common::Archive *pak = loadArchive(name, *it);
|
||||
_files.add(name, pak, 0, false);
|
||||
}
|
||||
} else if (_vm->game() == GI_KYRA1 || _vm->game() == GI_EOB1) {
|
||||
// We only need kyra.dat for the demo.
|
||||
if (_vm->gameFlags().isDemo && !_vm->gameFlags().isTalkie)
|
||||
return true;
|
||||
|
||||
if (!_vm->gameFlags().isDemo && _vm->gameFlags().isTalkie) {
|
||||
// List of files in the talkie version, which can never be unload.
|
||||
static const char *const list[] = {
|
||||
"ADL.PAK", "CHAPTER1.VRM", "COL.PAK", "FINALE.PAK", "INTRO1.PAK", "INTRO2.PAK",
|
||||
"INTRO3.PAK", "INTRO4.PAK", "MISC.PAK", "SND.PAK", "STARTUP.PAK", "XMI.PAK",
|
||||
"CAVE.APK", "DRAGON1.APK", "DRAGON2.APK", "LAGOON.APK", nullptr
|
||||
};
|
||||
|
||||
loadProtectedFiles(list);
|
||||
} else {
|
||||
// We only search in the game path to avoid any invalid PAK or
|
||||
// APK files from being picked up. This might happen, for example,
|
||||
// when the user has an Android package file in the CWD.
|
||||
Common::FSDirectory gameDir(dir);
|
||||
Common::ArchiveMemberList files;
|
||||
Common::ScopedPtr<Common::FSDirectory> gameDirRuntime;
|
||||
|
||||
gameDir.listMatchingMembers(files, "*.PAK");
|
||||
gameDir.listMatchingMembers(files, "*.APK");
|
||||
|
||||
if (_vm->gameFlags().platform == Common::Platform::kPlatformMacintosh) {
|
||||
gameDirRuntime.reset(gameDir.getSubDirectory("runtime"));
|
||||
if (gameDirRuntime) {
|
||||
gameDirRuntime->listMatchingMembers(files, "*.PAK");
|
||||
gameDirRuntime->listMatchingMembers(files, "*.APK");
|
||||
}
|
||||
}
|
||||
|
||||
for (Common::ArchiveMemberList::const_iterator i = files.begin(); i != files.end(); ++i) {
|
||||
Common::String name = (*i)->getName();
|
||||
name.toUppercase();
|
||||
|
||||
// No PAK file
|
||||
if (name == "TWMUSIC.PAK" || name == "EYE.PAK")
|
||||
continue;
|
||||
|
||||
// We need to only load the script archive for the language the user specified
|
||||
if (name == ((_vm->gameFlags().lang == Common::EN_ANY) ? "JMC.PAK" : "EMC.PAK"))
|
||||
continue;
|
||||
|
||||
Common::Archive *archive = loadArchive((*i)->getName(), *i);
|
||||
|
||||
if (archive) {
|
||||
// Hack for the Spanish version of EOB1. It has an invalid item.dat file in the
|
||||
// game directory that needs to have a lower priority than the one in EOBDATA6.PAK.
|
||||
bool highPrio = (_vm->game() == GI_EOB1 && _vm->gameFlags().lang == Common::ES_ESP && archive->hasFile("ITEM.DAT"));
|
||||
_files.add(name, archive, highPrio ? 4 : 0, false);
|
||||
}
|
||||
else {
|
||||
error("Couldn't load PAK file '%s'", name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (_vm->game() == GI_KYRA2) {
|
||||
if (_vm->gameFlags().useInstallerPackage)
|
||||
_files.add("installer", loadInstallerArchive("WESTWOOD", "%03d", 6), 2, false);
|
||||
|
||||
// mouse pointer, fonts, etc. required for initialization
|
||||
if (_vm->gameFlags().isDemo && !_vm->gameFlags().isTalkie) {
|
||||
loadPakFile("GENERAL.PAK");
|
||||
} else {
|
||||
loadPakFile("INTROGEN.PAK");
|
||||
loadPakFile("OTHER.PAK");
|
||||
}
|
||||
} else if (_vm->game() == GI_KYRA3) {
|
||||
loadPakFile("WESTWOOD.001");
|
||||
|
||||
if (!loadFileList("FILEDATA.FDT"))
|
||||
error("Couldn't load file: 'FILEDATA.FDT'");
|
||||
} else if (_vm->game() == GI_LOL) {
|
||||
if (_vm->gameFlags().useInstallerPackage)
|
||||
_files.add("installer", loadInstallerArchive("WESTWOOD", "%d", 0), 2, false);
|
||||
|
||||
if (!_vm->gameFlags().isTalkie && !_vm->gameFlags().isDemo) {
|
||||
static const char *const list[] = {
|
||||
"GENERAL.PAK", nullptr
|
||||
};
|
||||
|
||||
loadProtectedFiles(list);
|
||||
}
|
||||
} else if (_vm->game() != GI_EOB2) {
|
||||
error("Unknown game id: %d", _vm->game());
|
||||
return false; // for compilers that don't support NORETURN
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Resource::loadPakFile(const Common::Path &filename) {
|
||||
Common::Path filenameFixed(filename);
|
||||
filenameFixed.toUppercase();
|
||||
|
||||
Common::ArchiveMemberPtr file = _files.getMember(filenameFixed);
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
return loadPakFile(filenameFixed.toString('/'), file);
|
||||
}
|
||||
|
||||
bool Resource::loadPakFile(const Common::String &name, Common::ArchiveMemberPtr file) {
|
||||
Common::String nameFixed(name);
|
||||
nameFixed.toUppercase();
|
||||
|
||||
if (_archiveFiles.hasArchive(nameFixed) || _protectedFiles.hasArchive(nameFixed))
|
||||
return true;
|
||||
|
||||
Common::Archive *archive = loadArchive(nameFixed, file);
|
||||
if (!archive)
|
||||
return false;
|
||||
|
||||
_archiveFiles.add(nameFixed, archive, 0, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Resource::loadFileList(const Common::Path &filedata) {
|
||||
Common::SeekableReadStream *f = createReadStream(filedata);
|
||||
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
uint32 filenameOffset = 0;
|
||||
while ((filenameOffset = f->readUint32LE()) != 0) {
|
||||
uint32 offset = f->pos();
|
||||
f->seek(filenameOffset, SEEK_SET);
|
||||
|
||||
uint8 buffer[13];
|
||||
f->read(buffer, sizeof(buffer) - 1);
|
||||
buffer[12] = 0;
|
||||
f->seek(offset + 16, SEEK_SET);
|
||||
|
||||
Common::String filename = Common::String((char *)buffer);
|
||||
filename.toUppercase();
|
||||
|
||||
if (filename.hasSuffix(".PAK")) {
|
||||
Common::Path path(filename);
|
||||
if (!exists(path) && _vm->gameFlags().isDemo) {
|
||||
// the demo version supplied with Kyra3 does not
|
||||
// contain all pak files listed in filedata.fdt
|
||||
// so we don't do anything here if they are non
|
||||
// existent.
|
||||
} else if (!loadPakFile(path)) {
|
||||
delete f;
|
||||
error("couldn't load file '%s'", filename.c_str());
|
||||
return false; // for compilers that don't support NORETURN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete f;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Resource::loadFileList(const char *const *filelist, uint32 numFiles) {
|
||||
if (!filelist)
|
||||
return false;
|
||||
|
||||
while (numFiles--) {
|
||||
if (!loadPakFile(filelist[numFiles])) {
|
||||
error("couldn't load file '%s'", filelist[numFiles]);
|
||||
return false; // for compilers that don't support NORETURN
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Resource::loadProtectedFiles(const char *const *list) {
|
||||
for (uint i = 0; list[i]; ++i) {
|
||||
Common::ArchiveMemberPtr file = _files.getMember(list[i]);
|
||||
if (!file)
|
||||
error("Couldn't find PAK file '%s'", list[i]);
|
||||
|
||||
Common::Archive *archive = loadArchive(list[i], file);
|
||||
if (archive)
|
||||
_protectedFiles.add(list[i], archive, 0, false);
|
||||
else
|
||||
error("Couldn't load PAK file '%s'", list[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Resource::unloadPakFile(const Common::String &name, bool remFromCache) {
|
||||
Common::String nameFixed(name);
|
||||
nameFixed.toUppercase();
|
||||
|
||||
// We do not remove files from '_protectedFiles' here, since
|
||||
// those are protected against unloading.
|
||||
if (_archiveFiles.hasArchive(nameFixed)) {
|
||||
_archiveFiles.remove(nameFixed);
|
||||
if (remFromCache) {
|
||||
ArchiveMap::iterator iter = _archiveCache.find(nameFixed);
|
||||
if (iter != _archiveCache.end()) {
|
||||
delete iter->_value;
|
||||
_archiveCache.erase(nameFixed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Resource::isInPakList(const Common::String &name) {
|
||||
Common::String nameFixed(name);
|
||||
nameFixed.toUppercase();
|
||||
return (_archiveFiles.hasArchive(nameFixed) || _protectedFiles.hasArchive(nameFixed));
|
||||
}
|
||||
|
||||
bool Resource::isInCacheList(const Common::String &name) {
|
||||
Common::String nameFixed(name);
|
||||
nameFixed.toUppercase();
|
||||
return (_archiveCache.find(nameFixed) != _archiveCache.end());
|
||||
}
|
||||
|
||||
void Resource::unloadAllPakFiles() {
|
||||
_archiveFiles.clear();
|
||||
_protectedFiles.clear();
|
||||
}
|
||||
|
||||
void Resource::listFiles(const Common::Path &pattern, Common::ArchiveMemberList &list) {
|
||||
_files.listMatchingMembers(list, pattern);
|
||||
}
|
||||
|
||||
uint8 *Resource::fileData(const Common::Path &file, uint32 *size) {
|
||||
Common::SeekableReadStream *stream = createReadStream(file);
|
||||
if (!stream)
|
||||
return nullptr;
|
||||
|
||||
uint32 bufferSize = stream->size();
|
||||
uint8 *buffer = new uint8[bufferSize];
|
||||
assert(buffer);
|
||||
if (size)
|
||||
*size = bufferSize;
|
||||
stream->read(buffer, bufferSize);
|
||||
delete stream;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool Resource::exists(const Common::Path &file, bool errorOutOnFail) {
|
||||
if (_files.hasFile(file))
|
||||
return true;
|
||||
else if (errorOutOnFail)
|
||||
error("File '%s' can't be found", file.toString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 Resource::getFileSize(const Common::Path &file) {
|
||||
Common::SeekableReadStream *stream = createReadStream(file);
|
||||
if (!stream)
|
||||
return 0;
|
||||
|
||||
uint32 size = stream->size();
|
||||
delete stream;
|
||||
return size;
|
||||
}
|
||||
|
||||
bool Resource::loadFileToBuf(const Common::Path &file, void *buf, uint32 maxSize) {
|
||||
Common::SeekableReadStream *stream = createReadStream(file);
|
||||
if (!stream)
|
||||
return false;
|
||||
|
||||
memset(buf, 0, maxSize);
|
||||
stream->read(buf, ((int32)maxSize <= stream->size()) ? maxSize : stream->size());
|
||||
delete stream;
|
||||
return true;
|
||||
}
|
||||
|
||||
Common::Archive *Resource::getCachedArchive(const Common::String &file) const {
|
||||
ArchiveMap::iterator a = _archiveCache.find(file);
|
||||
return a != _archiveCache.end() ? a->_value : 0;
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *Resource::createReadStream(const Common::Path &file) {
|
||||
return _files.createReadStreamForMember(file);
|
||||
}
|
||||
|
||||
Common::SeekableReadStreamEndian *Resource::createEndianAwareReadStream(const Common::Path &file, int endianness) {
|
||||
Common::SeekableReadStream *stream = _files.createReadStreamForMember(file);
|
||||
return stream ? new Common::SeekableReadStreamEndianWrapper(stream, (endianness == kForceBE) ? true : (endianness == kForceLE ? false : _bigEndianPlatForm), DisposeAfterUse::YES) : nullptr;
|
||||
}
|
||||
|
||||
Common::Archive *Resource::loadArchive(const Common::String &name, Common::ArchiveMemberPtr member) {
|
||||
ArchiveMap::iterator cachedArchive = _archiveCache.find(name);
|
||||
if (cachedArchive != _archiveCache.end())
|
||||
return cachedArchive->_value;
|
||||
|
||||
Common::SeekableReadStream *stream = member->createReadStream();
|
||||
|
||||
if (!stream)
|
||||
return nullptr;
|
||||
|
||||
Common::Archive *archive = nullptr;
|
||||
for (LoaderList::const_iterator i = _loaders.begin(); i != _loaders.end(); ++i) {
|
||||
if ((*i)->checkFilename(name)) {
|
||||
if ((*i)->isLoadable(name, *stream)) {
|
||||
stream->seek(0, SEEK_SET);
|
||||
archive = (*i)->load(member, *stream);
|
||||
break;
|
||||
} else {
|
||||
stream->seek(0, SEEK_SET);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete stream;
|
||||
|
||||
if (!archive)
|
||||
return nullptr;
|
||||
|
||||
_archiveCache[name] = archive;
|
||||
return archive;
|
||||
}
|
||||
|
||||
Common::Archive *Resource::loadInstallerArchive(const Common::Path &file, const Common::String &ext, const uint8 offset) {
|
||||
Common::String name(file.toString('/'));
|
||||
ArchiveMap::iterator cachedArchive = _archiveCache.find(name);
|
||||
if (cachedArchive != _archiveCache.end())
|
||||
return cachedArchive->_value;
|
||||
|
||||
Common::Archive *archive = InstallerLoader::load(this, file, ext, offset);
|
||||
if (!archive)
|
||||
return nullptr;
|
||||
|
||||
_archiveCache[name] = archive;
|
||||
return archive;
|
||||
}
|
||||
|
||||
Common::Archive *Resource::loadStuffItArchive(const Common::Path &file, const Common::String &canonicalName) {
|
||||
ArchiveMap::iterator cachedArchive = _archiveCache.find(canonicalName);
|
||||
if (cachedArchive != _archiveCache.end())
|
||||
return cachedArchive->_value;
|
||||
|
||||
Common::Archive *archive = StuffItLoader::load(this, file);
|
||||
if (!archive)
|
||||
return nullptr;
|
||||
|
||||
_archiveCache[canonicalName] = archive;
|
||||
return archive;
|
||||
}
|
||||
|
||||
Common::Archive *Resource::loadStuffItArchive(Common::SeekableReadStream *stream, const Common::String &canonicalName, const Common::String &debugName) {
|
||||
ArchiveMap::iterator cachedArchive = _archiveCache.find(canonicalName);
|
||||
if (cachedArchive != _archiveCache.end()) {
|
||||
delete stream;
|
||||
return cachedArchive->_value;
|
||||
}
|
||||
|
||||
Common::Archive *archive = StuffItLoader::load(this, stream, debugName);
|
||||
if (!archive)
|
||||
return nullptr;
|
||||
|
||||
_archiveCache[canonicalName] = archive;
|
||||
return archive;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
void Resource::initializeLoaders() {
|
||||
_loaders.push_back(LoaderList::value_type(new ResLoaderPak()));
|
||||
_loaders.push_back(LoaderList::value_type(new ResLoaderInsMalcolm()));
|
||||
_loaders.push_back(LoaderList::value_type(new ResLoaderTlk()));
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
1418
engines/kyra/resource/resource.h
Normal file
1418
engines/kyra/resource/resource.h
Normal file
File diff suppressed because it is too large
Load Diff
1391
engines/kyra/resource/resource_intern.cpp
Normal file
1391
engines/kyra/resource/resource_intern.cpp
Normal file
File diff suppressed because it is too large
Load Diff
153
engines/kyra/resource/resource_intern.h
Normal file
153
engines/kyra/resource/resource_intern.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/* 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 KYRA_RESOURCE_INTERN_H
|
||||
#define KYRA_RESOURCE_INTERN_H
|
||||
|
||||
#include "common/archive.h"
|
||||
#include "common/hash-str.h"
|
||||
#include "common/hashmap.h"
|
||||
#include "common/str.h"
|
||||
#include "common/list.h"
|
||||
#include "common/macresman.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
class Resource;
|
||||
|
||||
class PlainArchive : public Common::Archive {
|
||||
public:
|
||||
struct Entry {
|
||||
Entry() : offset(0), size(0) {}
|
||||
Entry(uint32 o, uint32 s) : offset(o), size(s) {}
|
||||
|
||||
uint32 offset;
|
||||
uint32 size;
|
||||
};
|
||||
|
||||
PlainArchive(Common::ArchiveMemberPtr file);
|
||||
|
||||
void addFileEntry(const Common::Path &name, const Entry entry);
|
||||
Entry getFileEntry(const Common::Path &name) const;
|
||||
|
||||
// Common::Archive API implementation
|
||||
bool hasFile(const Common::Path &path) const override;
|
||||
int listMembers(Common::ArchiveMemberList &list) const override;
|
||||
const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
|
||||
Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
|
||||
private:
|
||||
typedef Common::HashMap<Common::Path, Entry, Common::Path::IgnoreCase_Hash, Common::Path::IgnoreCase_EqualTo> FileMap;
|
||||
|
||||
Common::ArchiveMemberPtr _file;
|
||||
FileMap _files;
|
||||
};
|
||||
|
||||
class TlkArchive : public Common::Archive {
|
||||
public:
|
||||
TlkArchive(Common::ArchiveMemberPtr file, uint16 entryCount, const uint32 *fileEntries);
|
||||
~TlkArchive() override;
|
||||
|
||||
bool hasFile(const Common::Path &path) const override;
|
||||
int listMembers(Common::ArchiveMemberList &list) const override;
|
||||
const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
|
||||
Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
|
||||
private:
|
||||
Common::ArchiveMemberPtr _file;
|
||||
|
||||
const uint32 *findFile(const Common::Path &path) const;
|
||||
|
||||
const uint16 _entryCount;
|
||||
const uint32 *const _fileEntries;
|
||||
};
|
||||
|
||||
class CachedArchive : public Common::Archive {
|
||||
public:
|
||||
struct InputEntry {
|
||||
Common::Path name;
|
||||
|
||||
byte *data;
|
||||
uint32 size;
|
||||
};
|
||||
|
||||
typedef Common::List<InputEntry> FileInputList;
|
||||
|
||||
CachedArchive(const FileInputList &files);
|
||||
~CachedArchive() override;
|
||||
|
||||
bool hasFile(const Common::Path &path) const override;
|
||||
int listMembers(Common::ArchiveMemberList &list) const override;
|
||||
const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
|
||||
Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
|
||||
private:
|
||||
struct Entry {
|
||||
byte *data;
|
||||
uint32 size;
|
||||
};
|
||||
|
||||
typedef Common::HashMap<Common::Path, Entry, Common::Path::IgnoreCase_Hash, Common::Path::IgnoreCase_EqualTo> FileMap;
|
||||
FileMap _files;
|
||||
};
|
||||
|
||||
|
||||
class ResArchiveLoader {
|
||||
public:
|
||||
virtual ~ResArchiveLoader() {}
|
||||
virtual bool checkFilename(const Common::String &filename) const = 0;
|
||||
virtual bool isLoadable(const Common::String &filename, Common::SeekableReadStream &stream) const = 0;
|
||||
virtual Common::Archive *load(Common::ArchiveMemberPtr file, Common::SeekableReadStream &stream) const = 0;
|
||||
};
|
||||
|
||||
class ResLoaderPak : public ResArchiveLoader {
|
||||
public:
|
||||
bool checkFilename(const Common::String &filename) const override;
|
||||
bool isLoadable(const Common::String &filename, Common::SeekableReadStream &stream) const override;
|
||||
Common::Archive *load(Common::ArchiveMemberPtr file, Common::SeekableReadStream &stream) const override;
|
||||
};
|
||||
|
||||
class ResLoaderInsMalcolm : public ResArchiveLoader {
|
||||
public:
|
||||
bool checkFilename(const Common::String &filename) const override;
|
||||
bool isLoadable(const Common::String &filename, Common::SeekableReadStream &stream) const override;
|
||||
Common::Archive *load(Common::ArchiveMemberPtr file, Common::SeekableReadStream &stream) const override;
|
||||
};
|
||||
|
||||
class ResLoaderTlk : public ResArchiveLoader {
|
||||
public:
|
||||
bool checkFilename(const Common::String &filename) const override;
|
||||
bool isLoadable(const Common::String &filename, Common::SeekableReadStream &stream) const override;
|
||||
Common::Archive *load(Common::ArchiveMemberPtr file, Common::SeekableReadStream &stream) const override;
|
||||
};
|
||||
|
||||
class InstallerLoader {
|
||||
public:
|
||||
static Common::Archive *load(Resource *owner, const Common::Path &filename, const Common::String &extension, const uint8 offset);
|
||||
};
|
||||
|
||||
class StuffItLoader {
|
||||
public:
|
||||
static Common::Archive *load(Resource *owner, const Common::Path &filename);
|
||||
static Common::Archive *load(Resource *owner, Common::SeekableReadStream *stream, const Common::String &debugName);
|
||||
};
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif
|
||||
138
engines/kyra/resource/resource_segacd.cpp
Normal file
138
engines/kyra/resource/resource_segacd.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
#include "kyra/resource/resource.h"
|
||||
#include "kyra/resource/resource_intern.h"
|
||||
#include "kyra/resource/resource_segacd.h"
|
||||
#include "common/substream.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
SegaCDResource::SegaCDResource(Resource *res) : _res(res), _str(0), _resTable(0), _numResources(0), _curOffset(0), _curSize(0) {
|
||||
}
|
||||
|
||||
SegaCDResource::~SegaCDResource() {
|
||||
unloadContainer();
|
||||
}
|
||||
|
||||
bool SegaCDResource::loadContainer(const Common::Path &filename, uint32 offset, uint32 size) {
|
||||
if (_curFile.equals(filename) && _curOffset == offset && _curSize == size)
|
||||
return true;
|
||||
|
||||
unloadContainer();
|
||||
|
||||
_str = _res->createEndianAwareReadStream(filename);
|
||||
if (!_str) {
|
||||
error("SegaCDResource: File '%s' not found.", filename.toString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
_str->seek(offset, SEEK_SET);
|
||||
uint32 first = _str->readUint32();
|
||||
_numResources = first >> 2;
|
||||
|
||||
if (_numResources & 0xFFFF0000) {
|
||||
_curFile.clear();
|
||||
_numResources = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 1; i < _numResources; ++i) {
|
||||
uint32 next = _str->readUint32();
|
||||
if (next == 0) {
|
||||
_numResources = i;
|
||||
} else if (next < first) {
|
||||
first = next;
|
||||
_numResources = first >> 2;
|
||||
}
|
||||
}
|
||||
|
||||
_str->seek(offset, SEEK_SET);
|
||||
_resTable = new TableEntry[_numResources];
|
||||
for (int i = 0; i < _numResources; ++i)
|
||||
_resTable[i]._offset = offset + _str->readUint32();
|
||||
|
||||
if (size)
|
||||
assert(offset + size <= (uint32)_str->size());
|
||||
|
||||
for (int i = 0; i < _numResources; ++i) {
|
||||
uint32 next = size ? offset + size : _str->size();
|
||||
for (int ii = 0; ii < _numResources; ++ii) {
|
||||
if (_resTable[ii]._offset <= _resTable[i]._offset)
|
||||
continue;
|
||||
next = MIN<uint32>(_resTable[ii]._offset, next);
|
||||
}
|
||||
_resTable[i]._len = next - _resTable[i]._offset;
|
||||
}
|
||||
|
||||
_curFile = filename;
|
||||
_curOffset = offset;
|
||||
_curSize = size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SegaCDResource::unloadContainer() {
|
||||
delete[] _resTable;
|
||||
delete _str;
|
||||
_resTable = 0;
|
||||
_numResources = 0;
|
||||
_str = 0;
|
||||
}
|
||||
|
||||
Common::SeekableReadStreamEndian *SegaCDResource::resStreamEndian(int resID) {
|
||||
if (!_str || !_resTable || resID >= _numResources)
|
||||
return 0;
|
||||
|
||||
Common::SeekableReadStream *str = resStream(resID);
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
return new Common::SeekableReadStreamEndianWrapper(str, _str->isBE(), DisposeAfterUse::YES);
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *SegaCDResource::resStream(int resID) {
|
||||
if (!_str || !_resTable || resID >= _numResources)
|
||||
return 0;
|
||||
|
||||
return new Common::SeekableSubReadStream(_str, _resTable[resID]._offset, _resTable[resID]._offset + _resTable[resID]._len, DisposeAfterUse::NO);
|
||||
}
|
||||
|
||||
uint8 *SegaCDResource::resData(int resID, uint32 *resLen) {
|
||||
if (!_str || !_resTable || resID >= _numResources)
|
||||
return 0;
|
||||
|
||||
uint8 *res = new uint8[_resTable[resID]._len];
|
||||
|
||||
_str->seek(_resTable[resID]._offset, SEEK_SET);
|
||||
_str->read(res, _resTable[resID]._len);
|
||||
|
||||
if (resLen)
|
||||
*resLen = _resTable[resID]._len;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_EOB
|
||||
71
engines/kyra/resource/resource_segacd.h
Normal file
71
engines/kyra/resource/resource_segacd.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_EOB
|
||||
|
||||
#ifndef KYRA_RESOURCE_SEGACD_H
|
||||
#define KYRA_RESOURCE_SEGACD_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/str.h"
|
||||
|
||||
namespace Common {
|
||||
class SeekableReadStream;
|
||||
class SeekableReadStreamEndian;
|
||||
}
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
class Resource;
|
||||
class SegaCDResource {
|
||||
public:
|
||||
SegaCDResource(Resource *res);
|
||||
~SegaCDResource();
|
||||
|
||||
bool loadContainer(const Common::Path &filename, uint32 offset = 0, uint32 size = 0);
|
||||
void unloadContainer();
|
||||
|
||||
Common::SeekableReadStreamEndian *resStreamEndian(int resID);
|
||||
Common::SeekableReadStream *resStream(int resID);
|
||||
|
||||
uint8 *resData(int resID, uint32 *resLen = 0);
|
||||
|
||||
private:
|
||||
Resource *_res;
|
||||
|
||||
struct TableEntry {
|
||||
TableEntry() : _offset(0), _len(0) {}
|
||||
uint32 _offset;
|
||||
uint32 _len;
|
||||
};
|
||||
|
||||
TableEntry *_resTable;
|
||||
int _numResources;
|
||||
Common::SeekableReadStreamEndian *_str;
|
||||
Common::Path _curFile;
|
||||
uint32 _curOffset;
|
||||
uint32 _curSize;
|
||||
};
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif
|
||||
#endif // ENABLE_EOB
|
||||
2237
engines/kyra/resource/staticres.cpp
Normal file
2237
engines/kyra/resource/staticres.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2087
engines/kyra/resource/staticres_eob.cpp
Normal file
2087
engines/kyra/resource/staticres_eob.cpp
Normal file
File diff suppressed because it is too large
Load Diff
907
engines/kyra/resource/staticres_lol.cpp
Normal file
907
engines/kyra/resource/staticres_lol.cpp
Normal file
@@ -0,0 +1,907 @@
|
||||
/* 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 "kyra/resource/resource.h"
|
||||
#include "kyra/engine/lol.h"
|
||||
#include "kyra/graphics/screen_lol.h"
|
||||
#include "kyra/gui/gui_lol.h"
|
||||
#include "kyra/sound/sound_intern.h"
|
||||
|
||||
#ifdef ENABLE_LOL
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
const LoLCharacter *StaticResource::loadCharData(int id, int &entries) {
|
||||
return (const LoLCharacter *)getData(id, kLoLCharData, entries);
|
||||
}
|
||||
|
||||
const SpellProperty *StaticResource::loadSpellData(int id, int &entries) {
|
||||
return (const SpellProperty *)getData(id, kLoLSpellData, entries);
|
||||
}
|
||||
|
||||
const CompassDef *StaticResource::loadCompassData(int id, int &entries) {
|
||||
return (const CompassDef *)getData(id, kLoLCompassData, entries);
|
||||
}
|
||||
|
||||
const FlyingObjectShape *StaticResource::loadFlyingObjectData(int id, int &entries) {
|
||||
return (const FlyingObjectShape *)getData(id, kLoLFlightShpData, entries);
|
||||
}
|
||||
|
||||
const LoLButtonDef *StaticResource::loadButtonDefs(int id, int &entries) {
|
||||
return (const LoLButtonDef *)getData(id, kLoLButtonData, entries);
|
||||
}
|
||||
|
||||
bool StaticResource::loadCharData(Common::SeekableReadStream &stream, void *&ptr, int &size) {
|
||||
size = stream.size() / 130;
|
||||
LoLCharacter *charData = new LoLCharacter[size];
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
LoLCharacter *t = &charData[i];
|
||||
|
||||
t->flags = stream.readUint16LE();
|
||||
stream.read(t->name, 11);
|
||||
t->raceClassSex = stream.readByte();
|
||||
t->id = stream.readSint16LE();
|
||||
t->curFaceFrame = stream.readByte();
|
||||
t->tempFaceFrame = stream.readByte();
|
||||
t->screamSfx = stream.readByte();
|
||||
stream.readUint32LE();
|
||||
for (int ii = 0; ii < 8; ii++)
|
||||
t->itemsMight[ii] = stream.readUint16LE();
|
||||
for (int ii = 0; ii < 8; ii++)
|
||||
t->protectionAgainstItems[ii] = stream.readUint16LE();
|
||||
t->itemProtection = stream.readUint16LE();
|
||||
t->hitPointsCur = stream.readSint16LE();
|
||||
t->hitPointsMax = stream.readUint16LE();
|
||||
t->magicPointsCur = stream.readSint16LE();
|
||||
t->magicPointsMax = stream.readUint16LE();
|
||||
t->field_41 = stream.readByte();
|
||||
t->damageSuffered = stream.readUint16LE();
|
||||
t->weaponHit = stream.readUint16LE();
|
||||
t->totalMightModifier = stream.readUint16LE();
|
||||
t->totalProtectionModifier = stream.readUint16LE();
|
||||
t->might = stream.readUint16LE();
|
||||
t->protection = stream.readUint16LE();
|
||||
t->nextAnimUpdateCountdown = stream.readSint16LE();
|
||||
for (int ii = 0; ii < 11; ii++)
|
||||
t->items[ii] = stream.readUint16LE();
|
||||
for (int ii = 0; ii < 3; ii++)
|
||||
t->skillLevels[ii] = stream.readByte();
|
||||
for (int ii = 0; ii < 3; ii++)
|
||||
t->skillModifiers[ii] = stream.readByte();
|
||||
for (int ii = 0; ii < 3; ii++)
|
||||
t->experiencePts[ii] = stream.readUint32LE();
|
||||
for (int ii = 0; ii < 5; ii++)
|
||||
t->characterUpdateEvents[ii] = stream.readByte();
|
||||
for (int ii = 0; ii < 5; ii++)
|
||||
t->characterUpdateDelay[ii] = stream.readByte();
|
||||
};
|
||||
|
||||
ptr = charData;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StaticResource::loadSpellData(Common::SeekableReadStream &stream, void *&ptr, int &size) {
|
||||
size = stream.size() / 28;
|
||||
SpellProperty *spellData = new SpellProperty[size];
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
SpellProperty *t = &spellData[i];
|
||||
|
||||
t->spellNameCode = stream.readUint16LE();
|
||||
for (int ii = 0; ii < 4; ii++)
|
||||
t->mpRequired[ii] = stream.readUint16LE();
|
||||
t->field_a = stream.readUint16LE();
|
||||
t->field_c = stream.readUint16LE();
|
||||
for (int ii = 0; ii < 4; ii++)
|
||||
t->hpRequired[ii] = stream.readUint16LE();
|
||||
t->field_16 = stream.readUint16LE();
|
||||
t->field_18 = stream.readUint16LE();
|
||||
t->flags = stream.readUint16LE();
|
||||
};
|
||||
|
||||
ptr = spellData;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StaticResource::loadCompassData(Common::SeekableReadStream &stream, void *&ptr, int &size) {
|
||||
size = stream.size() / 4;
|
||||
CompassDef *defs = new CompassDef[size];
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
CompassDef *t = &defs[i];
|
||||
t->shapeIndex = stream.readByte();
|
||||
t->x = stream.readByte();
|
||||
t->y = stream.readByte();
|
||||
t->flags = stream.readByte();
|
||||
};
|
||||
|
||||
|
||||
ptr = defs;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StaticResource::loadFlyingObjectData(Common::SeekableReadStream &stream, void *&ptr, int &size) {
|
||||
size = stream.size() / 5;
|
||||
FlyingObjectShape *defs = new FlyingObjectShape[size];
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
FlyingObjectShape *t = &defs[i];
|
||||
t->shapeFront = stream.readByte();
|
||||
t->shapeBack = stream.readByte();
|
||||
t->shapeLeft = stream.readByte();
|
||||
t->drawFlags = stream.readByte();
|
||||
t->flipFlags = stream.readByte();
|
||||
};
|
||||
|
||||
ptr = defs;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StaticResource::loadButtonDefs(Common::SeekableReadStream &stream, void *&ptr, int &size) {
|
||||
size = stream.size() / 18;
|
||||
|
||||
LoLButtonDef *r = new LoLButtonDef[size];
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
r[i].buttonflags = stream.readUint16BE();
|
||||
r[i].keyCode = stream.readUint16BE();
|
||||
r[i].keyCode2 = stream.readUint16BE();
|
||||
r[i].x = stream.readSint16BE();
|
||||
r[i].y = stream.readSint16BE();
|
||||
r[i].w = stream.readUint16BE();
|
||||
r[i].h = stream.readUint16BE();
|
||||
r[i].index = stream.readUint16BE();
|
||||
r[i].screenDim = stream.readUint16BE();
|
||||
}
|
||||
|
||||
ptr = r;
|
||||
return true;
|
||||
}
|
||||
|
||||
void StaticResource::freeCharData(void *&ptr, int &size) {
|
||||
LoLCharacter *d = (LoLCharacter *)ptr;
|
||||
delete[] d;
|
||||
ptr = 0;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
void StaticResource::freeSpellData(void *&ptr, int &size) {
|
||||
SpellProperty *d = (SpellProperty *)ptr;
|
||||
delete[] d;
|
||||
ptr = 0;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
void StaticResource::freeCompassData(void *&ptr, int &size) {
|
||||
CompassDef *d = (CompassDef *)ptr;
|
||||
delete[] d;
|
||||
ptr = 0;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
void StaticResource::freeFlyingObjectData(void *&ptr, int &size) {
|
||||
FlyingObjectShape *d = (FlyingObjectShape *)ptr;
|
||||
delete[] d;
|
||||
ptr = 0;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
void StaticResource::freeButtonDefs(void *&ptr, int &size) {
|
||||
LoLButtonDef *d = (LoLButtonDef *)ptr;
|
||||
delete[] d;
|
||||
ptr = 0;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
void LoLEngine::initStaticResource() {
|
||||
// assign music resource data.
|
||||
if (_flags.platform == Common::kPlatformDOS) {
|
||||
if (_flags.isDemo) {
|
||||
static const char *const file[] = { "LOREDEMO" };
|
||||
SoundResourceInfo_PC resInfoDemo(file, ARRAYSIZE(file));
|
||||
_sound->initAudioResourceInfo(kMusicIntro, &resInfoDemo);
|
||||
} else {
|
||||
static const char *const intro[] = { "LOREINTR" };
|
||||
static const char *const finale[] = { "LOREFINL" };
|
||||
SoundResourceInfo_PC resInfoIntro(intro, ARRAYSIZE(intro));
|
||||
SoundResourceInfo_PC resInfoFinale(finale, ARRAYSIZE(finale));
|
||||
_sound->initAudioResourceInfo(kMusicIntro, &resInfoIntro);
|
||||
// In game music file handling is different, thus does not need a file list.
|
||||
_sound->initAudioResourceInfo(kMusicFinale, &resInfoFinale);
|
||||
}
|
||||
} else if (_flags.platform == Common::kPlatformPC98) {
|
||||
static const char *const fileListIntro[] = { 0, "lore84.86", "lore82.86", 0, 0, 0, "lore83.86", "lore81.86" };
|
||||
static const char *const fileListFinale[] = { 0, 0, "lore85.86", "lore86.86", "lore87.86" };
|
||||
SoundResourceInfo_TownsPC98V2 resInfoIntro(fileListIntro, ARRAYSIZE(fileListIntro), 0, 0, 0);
|
||||
SoundResourceInfo_TownsPC98V2 resInfoIngame(0, 0, "lore%02d.86", 0, 0);
|
||||
SoundResourceInfo_TownsPC98V2 resInfoFinale(fileListFinale, ARRAYSIZE(fileListFinale), 0, 0, 0);
|
||||
_sound->initAudioResourceInfo(kMusicIntro, &resInfoIntro);
|
||||
_sound->initAudioResourceInfo(kMusicIngame, &resInfoIngame);
|
||||
_sound->initAudioResourceInfo(kMusicFinale, &resInfoFinale);
|
||||
} else if (_flags.platform == Common::kPlatformFMTowns) {
|
||||
static const char *const fileListIntro[] = { 0, "lore84.twn", "lore82.twn", 0, 0, 0, "lore83.twn", "lore81.twn" };
|
||||
static const char *const fileListFinale[] = { 0, 0, "lore85.twn", "lore86.twn", "lore87.twn" };
|
||||
SoundResourceInfo_TownsPC98V2 resInfoIntro(fileListIntro, ARRAYSIZE(fileListIntro), 0, 0, 0);
|
||||
SoundResourceInfo_TownsPC98V2 resInfoIngame(0, 0, "lore%02d.twn", 0, 0);
|
||||
SoundResourceInfo_TownsPC98V2 resInfoFinale(fileListFinale, ARRAYSIZE(fileListFinale), 0, 0, 0);
|
||||
_sound->initAudioResourceInfo(kMusicIntro, &resInfoIntro);
|
||||
_sound->initAudioResourceInfo(kMusicIngame, &resInfoIngame);
|
||||
_sound->initAudioResourceInfo(kMusicFinale, &resInfoFinale);
|
||||
}
|
||||
|
||||
if (_flags.isDemo && !_flags.isTalkie)
|
||||
return;
|
||||
|
||||
int tempSize;
|
||||
_pakFileList = _staticres->loadStrings(kLoLIngamePakFiles, _pakFileListSize);
|
||||
_charDefaults = _staticres->loadCharData(kLoLCharacterDefs, _charDefaultsSize);
|
||||
_ingameSoundIndex = (const int16 *)_staticres->loadRawDataBe16(kLoLIngameSfxIndex, _ingameSoundIndexSize);
|
||||
_musicTrackMap = _staticres->loadRawData(kLoLMusicTrackMap, tempSize);
|
||||
_ingameGMSoundIndex = _staticres->loadRawData(kLoLIngameGMSfxIndex, _ingameGMSoundIndexSize);
|
||||
_ingameMT32SoundIndex = _staticres->loadRawData(kLoLIngameMT32SfxIndex, _ingameMT32SoundIndexSize);
|
||||
_ingamePCSpeakerSoundIndex = _staticres->loadRawData(kLoLIngamePcSpkSfxIndex, _ingamePCSpeakerSoundIndexSize);
|
||||
_spellProperties = _staticres->loadSpellData(kLoLSpellProperties, tempSize);
|
||||
_gameShapeMap = (const int8 *)_staticres->loadRawData(kLoLGameShapeMap, tempSize);
|
||||
_sceneItemOffs = (const int8 *)_staticres->loadRawData(kLoLSceneItemOffs, tempSize);
|
||||
_charInvIndex = _staticres->loadRawData(kLoLCharInvIndex, tempSize);
|
||||
_charInvDefs = _staticres->loadRawData(kLoLCharInvDefs, tempSize);
|
||||
_charDefsMan = _staticres->loadRawDataBe16(kLoLCharDefsMan, tempSize);
|
||||
_charDefsWoman = _staticres->loadRawDataBe16(kLoLCharDefsWoman, tempSize);
|
||||
_charDefsKieran = _staticres->loadRawDataBe16(kLoLCharDefsKieran, tempSize);
|
||||
_charDefsAkshel = _staticres->loadRawDataBe16(kLoLCharDefsAkshel, tempSize);
|
||||
_expRequirements = (const int32 *)_staticres->loadRawDataBe32(kLoLExpRequirements, tempSize);
|
||||
_monsterModifiers1 = _staticres->loadRawDataBe16(kLoLMonsterModifiers1, tempSize);
|
||||
_monsterModifiers2 = _staticres->loadRawDataBe16(kLoLMonsterModifiers2, tempSize);
|
||||
_monsterModifiers3 = _staticres->loadRawDataBe16(kLoLMonsterModifiers3, tempSize);
|
||||
_monsterModifiers4 = _staticres->loadRawDataBe16(kLoLMonsterModifiers4, tempSize);
|
||||
_monsterShiftOffs = (const int8 *)_staticres->loadRawData(kLoLMonsterShiftOffsets, tempSize);
|
||||
_monsterDirFlags = _staticres->loadRawData(kLoLMonsterDirFlags, tempSize);
|
||||
_monsterScaleX = _staticres->loadRawData(kLoLMonsterScaleX, tempSize);
|
||||
_monsterScaleY = _staticres->loadRawData(kLoLMonsterScaleY, tempSize);
|
||||
_monsterScaleWH = _staticres->loadRawDataBe16(kLoLMonsterScaleWH, tempSize);
|
||||
_inventorySlotDesc = _staticres->loadRawDataBe16(kLoLInventoryDesc, tempSize);
|
||||
_levelShpList = _staticres->loadStrings(kLoLLevelShpList, tempSize);
|
||||
_levelDatList = _staticres->loadStrings(kLoLLevelDatList, tempSize);
|
||||
_compassDefs = _staticres->loadCompassData(kLoLCompassDefs, tempSize);
|
||||
_flyingItemShapes = _staticres->loadFlyingObjectData(kLoLFlyingObjectShp, tempSize);
|
||||
_itemCost = _staticres->loadRawDataBe16(kLoLItemPrices, tempSize);
|
||||
_stashSetupData = _staticres->loadRawData(kLoLStashSetup, tempSize);
|
||||
|
||||
_dscWalls = (const int8 *)_staticres->loadRawData(kLoLDscWalls, tempSize);
|
||||
|
||||
_dscOvlMap = _staticres->loadRawData(kLoLDscOvlMap, tempSize);
|
||||
_dscShapeOvlIndex = _staticres->loadRawData(kLoLDscOvlIndex, tempSize);
|
||||
_dscShapeScaleW = _staticres->loadRawDataBe16(kLoLDscScaleWidthData, tempSize);
|
||||
_dscShapeScaleH = _staticres->loadRawDataBe16(kLoLDscScaleHeightData, tempSize);
|
||||
_dscShapeY = (const int8 *)_staticres->loadRawData(kLoLBaseDscY, tempSize);
|
||||
|
||||
_dscDoorMonsterScaleTable = _staticres->loadRawDataBe16(kLoLDscDoorScale, tempSize);
|
||||
_dscDoor4 = _staticres->loadRawDataBe16(kLoLDscDoor4, tempSize);
|
||||
_dscDoorMonsterX = (const int16 *)_staticres->loadRawDataBe16(kLoLDscDoorX, tempSize);
|
||||
_dscDoorMonsterY = (const int16 *)_staticres->loadRawDataBe16(kLoLDscDoorY, tempSize);
|
||||
|
||||
_scrollXTop = _staticres->loadRawData(kLoLScrollXTop, tempSize);
|
||||
_scrollYTop = _staticres->loadRawData(kLoLScrollYTop, tempSize);
|
||||
_scrollXBottom = _staticres->loadRawData(kLoLScrollXBottom, tempSize);
|
||||
_scrollYBottom = _staticres->loadRawData(kLoLScrollYBottom, tempSize);
|
||||
|
||||
const char *const *tmpSndList = _staticres->loadStrings(kLoLIngameSfxFiles, _ingameSoundListSize);
|
||||
if (tmpSndList) {
|
||||
_ingameSoundList.reserve(_ingameSoundListSize);
|
||||
for (int i = 0; i < _ingameSoundListSize; i++)
|
||||
_ingameSoundList.push_back(Common::String(tmpSndList[i]));
|
||||
_staticres->unloadId(kLoLIngameSfxFiles);
|
||||
}
|
||||
|
||||
_buttonData = _staticres->loadButtonDefs(kLoLButtonDefs, tempSize);
|
||||
_buttonList1 = _staticres->loadRawData(kLoLButtonList1, tempSize);
|
||||
_buttonList2 = _staticres->loadRawData(kLoLButtonList2, tempSize);
|
||||
_buttonList3 = _staticres->loadRawData(kLoLButtonList3, tempSize);
|
||||
_buttonList4 = _staticres->loadRawData(kLoLButtonList4, tempSize);
|
||||
_buttonList5 = _staticres->loadRawData(kLoLButtonList5, tempSize);
|
||||
_buttonList6 = _staticres->loadRawData(kLoLButtonList6, tempSize);
|
||||
_buttonList7 = _staticres->loadRawData(kLoLButtonList7, tempSize);
|
||||
_buttonList8 = _staticres->loadRawData(kLoLButtonList8, tempSize);
|
||||
|
||||
_autoMapStrings = _staticres->loadRawDataBe16(kLoLMapStringId, tempSize);
|
||||
|
||||
const uint8 *tmp = _staticres->loadRawData(kLoLLegendData, tempSize);
|
||||
uint8 entrySize = tempSize / 12;
|
||||
tempSize /= entrySize;
|
||||
if (tempSize) {
|
||||
_defaultLegendData = new MapLegendData[tempSize];
|
||||
for (int i = 0; i < tempSize; i++) {
|
||||
_defaultLegendData[i].shapeIndex = *tmp++;
|
||||
_defaultLegendData[i].enable = *tmp++ ? true : false;
|
||||
_defaultLegendData[i].y = (entrySize == 5) ? (int8)*tmp++ : (i == 10 ? -5 : 0);
|
||||
_defaultLegendData[i].stringId = READ_LE_UINT16(tmp);
|
||||
tmp += 2;
|
||||
}
|
||||
_staticres->unloadId(kLoLLegendData);
|
||||
}
|
||||
|
||||
tmp = _staticres->loadRawData(kLoLMapCursorOvl, tempSize);
|
||||
if (tmp) {
|
||||
_mapCursorOverlay = new uint8[tempSize];
|
||||
memcpy(_mapCursorOverlay, tmp, tempSize);
|
||||
_staticres->unloadId(kLoLMapCursorOvl);
|
||||
}
|
||||
|
||||
_updateSpellBookCoords = _staticres->loadRawData(kLoLSpellbookCoords, tempSize);
|
||||
_updateSpellBookAnimData = _staticres->loadRawData(kLoLSpellbookAnim, tempSize);
|
||||
_healShapeFrames = _staticres->loadRawData(kLoLHealShapeFrames, tempSize);
|
||||
|
||||
tmp = _staticres->loadRawData(kLoLLightningDefs, tempSize);
|
||||
if (tmp) {
|
||||
_lightningProps = new LightningProperty[5];
|
||||
for (int i = 0; i < 5; i++) {
|
||||
_lightningProps[i].lastFrame = tmp[i << 2];
|
||||
_lightningProps[i].frameDiv = tmp[(i << 2) + 1];
|
||||
_lightningProps[i].sfxId = READ_LE_UINT16(&tmp[(i << 2) + 2]);
|
||||
}
|
||||
_staticres->unloadId(kLoLLightningDefs);
|
||||
}
|
||||
|
||||
_fireBallCoords = (const int16 *)_staticres->loadRawDataBe16(kLoLFireballCoords, tempSize);
|
||||
|
||||
_buttonCallbacks.clear();
|
||||
_buttonCallbacks.reserve(95);
|
||||
#define cb(x) _buttonCallbacks.push_back(BUTTON_FUNCTOR(LoLEngine, this, &LoLEngine::x))
|
||||
// 0x00
|
||||
cb(clickedUpArrow);
|
||||
cb(clickedDownArrow);
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[1]);
|
||||
cb(clickedLeftArrow);
|
||||
|
||||
// 0x04
|
||||
cb(clickedRightArrow);
|
||||
cb(clickedTurnLeftArrow);
|
||||
cb(clickedTurnRightArrow);
|
||||
cb(clickedAttackButton);
|
||||
|
||||
// 0x08
|
||||
for (int i = 0; i < 3; ++i)
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[7]);
|
||||
cb(clickedMagicButton);
|
||||
|
||||
// 0x0C
|
||||
for (int i = 0; i < 3; ++i)
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[11]);
|
||||
cb(clickedMagicSubmenu);
|
||||
|
||||
// 0x10
|
||||
cb(clickedScreen);
|
||||
cb(clickedPortraitLeft);
|
||||
for (int i = 0; i < 7; ++i)
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[17]);
|
||||
|
||||
// 0x19
|
||||
cb(clickedLiveMagicBarsLeft);
|
||||
for (int i = 0; i < 3; ++i)
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[25]);
|
||||
|
||||
// 0x1D
|
||||
cb(clickedPortraitEtcRight);
|
||||
for (int i = 0; i < 3; ++i)
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[29]);
|
||||
|
||||
// 0x21
|
||||
cb(clickedCharInventorySlot);
|
||||
for (int i = 0; i < 10; ++i)
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[33]);
|
||||
|
||||
// 0x2C
|
||||
cb(clickedExitCharInventory);
|
||||
cb(clickedSceneDropItem);
|
||||
for (int i = 0; i < 3; ++i)
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[45]);
|
||||
|
||||
// 0x31
|
||||
cb(clickedScenePickupItem);
|
||||
cb(clickedInventorySlot);
|
||||
for (int i = 0; i < 9; ++i)
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[50]);
|
||||
|
||||
// 0x3C
|
||||
cb(clickedInventoryScroll);
|
||||
cb(clickedInventoryScroll);
|
||||
cb(clickedWall);
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[62]);
|
||||
|
||||
// 0x40
|
||||
cb(clickedSequenceWindow);
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[0]);
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[1]);
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[3]);
|
||||
|
||||
// 0x44
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[4]);
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[5]);
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[6]);
|
||||
cb(clickedScroll);
|
||||
|
||||
// 0x48
|
||||
for (int i = 0; i < 9; ++i)
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[71]);
|
||||
|
||||
// 0x51
|
||||
cb(clickedSpellTargetCharacter);
|
||||
for (int i = 0; i < 3; ++i)
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[81]);
|
||||
|
||||
// 0x55
|
||||
cb(clickedSpellTargetScene);
|
||||
cb(clickedSceneThrowItem);
|
||||
_buttonCallbacks.push_back(_buttonCallbacks[86]);
|
||||
|
||||
// 0x58
|
||||
cb(clickedOptions);
|
||||
cb(clickedRestParty);
|
||||
cb(clickedMoneyBox);
|
||||
cb(clickedCompass);
|
||||
|
||||
// 0x5C
|
||||
cb(clickedAutomap);
|
||||
cb(clickedLamp);
|
||||
cb(clickedStatusIcon);
|
||||
#undef cb
|
||||
}
|
||||
|
||||
void GUI_LoL::initStaticData() {
|
||||
GUI_V2_BUTTON(_scrollUpButton, 20, 96, 0, 1, 1, 1, 0x4487, 0, 0, 0, 25, 16, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0);
|
||||
GUI_V2_BUTTON(_scrollDownButton, 21, 98, 0, 1, 1, 1, 0x4487, 0, 0, 0, 25, 16, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0);
|
||||
|
||||
for (uint i = 0; i < ARRAYSIZE(_menuButtons); ++i)
|
||||
GUI_V2_BUTTON(_menuButtons[i], i, 0, 0, 0, 0, 0, 0x4487, 0, 0, 0, 0, 0, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0);
|
||||
|
||||
if (_vm->gameFlags().isTalkie)
|
||||
GUI_LOL_MENU(_mainMenu, 9, 0x4000, 0, 7, -1, -1, -1, -1);
|
||||
else
|
||||
GUI_LOL_MENU(_mainMenu, 17, 0x4000, 0, 6, -1, -1, -1, -1);
|
||||
|
||||
int buttonHeight = _vm->gameFlags().lang == Common::Language::ZH_TWN ? 20 : 15;
|
||||
int buttonStep = _vm->gameFlags().lang == Common::Language::ZH_TWN ? 21 : 17;
|
||||
int titleSkip = _vm->gameFlags().lang == Common::Language::ZH_TWN ? 26 : 22;
|
||||
int saveListYStart = _vm->gameFlags().lang == Common::Language::ZH_TWN ? 44 : 39;
|
||||
int saveListYOK = _vm->gameFlags().lang == Common::Language::ZH_TWN ? 114 : 118;
|
||||
|
||||
int row = 0;
|
||||
|
||||
for (row = 0; row < 4; row++)
|
||||
GUI_LOL_MENU_ITEM(_mainMenu.item[row], 0x4001 + row, 16, titleSkip + 1 + row * buttonStep, 176, buttonHeight, 0, 0);
|
||||
|
||||
if (_vm->gameFlags().isTalkie) {
|
||||
GUI_LOL_MENU_ITEM(_mainMenu.item[row], 0x42D9, 16, titleSkip + 1 + row * buttonStep, 176, buttonHeight, 0, 0);
|
||||
row++;
|
||||
}
|
||||
GUI_LOL_MENU_ITEM(_mainMenu.item[row], 0x4006, 16, titleSkip + 1 + row * buttonStep, 176, buttonHeight, 0, 0); row++;
|
||||
GUI_LOL_MENU_ITEM(_mainMenu.item[row], 0x4005, 88, titleSkip + 1 + row * buttonStep + 2, 104, buttonHeight, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]); row++;
|
||||
|
||||
Button::Callback mainMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedMainMenu);
|
||||
for (int i = 0; i < _mainMenu.numberOfItems; ++i)
|
||||
_mainMenu.item[i].callback = mainMenuFunctor;
|
||||
|
||||
GUI_LOL_MENU(_loadMenu, 10, 0x400E, 1, 5, 128, 20, 128, 118);
|
||||
for (row = 0; row < 4; row++)
|
||||
GUI_LOL_MENU_ITEM(_loadMenu.item[row], 0xFFFE - row, 8, saveListYStart + row * buttonStep, 256, buttonHeight, 0, 0);
|
||||
GUI_LOL_MENU_ITEM(_loadMenu.item[4], 0x4011, 168, saveListYOK, 96, buttonHeight, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]);
|
||||
Button::Callback loadMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedLoadMenu);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
_loadMenu.item[i].callback = loadMenuFunctor;
|
||||
|
||||
GUI_LOL_MENU(_saveMenu, 10, 0x400D, 1, 5, 128, 20, 128, 118);
|
||||
for (row = 0; row < 4; row++)
|
||||
GUI_LOL_MENU_ITEM(_saveMenu.item[row], 0xFFFE - row, 8, saveListYStart + row * buttonStep, 256, buttonHeight, 0, 0);
|
||||
GUI_LOL_MENU_ITEM(_saveMenu.item[4], 0x4011, 168, saveListYOK, 96, buttonHeight, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]);
|
||||
Button::Callback saveMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedSaveMenu);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
_saveMenu.item[i].callback = saveMenuFunctor;
|
||||
|
||||
GUI_LOL_MENU(_deleteMenu, 10, 0x400F, 1, 5, 128, 20, 128, 118);
|
||||
for (row = 0; row < 4; row++)
|
||||
GUI_LOL_MENU_ITEM(_deleteMenu.item[row], 0xFFFE - row, 8, saveListYStart + row * buttonStep, 256, buttonHeight, 0, 0);
|
||||
GUI_LOL_MENU_ITEM(_deleteMenu.item[4], 0x4011, 168, saveListYOK, 96, buttonHeight, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]);
|
||||
Button::Callback deleteMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedDeleteMenu);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
_deleteMenu.item[i].callback = deleteMenuFunctor;
|
||||
|
||||
GUI_LOL_MENU(_gameOptions, 17, 0x400C, 0, 6, -1, -1, -1, -1);
|
||||
row = 0;
|
||||
if (!_vm->gameFlags().isTalkie) {
|
||||
GUI_LOL_MENU_ITEM(_gameOptions.item[row], 0xFFF9, 120, titleSkip + row * buttonStep, 80, buttonHeight, 0x406A, 0); row++;
|
||||
GUI_LOL_MENU_ITEM(_gameOptions.item[row], 0xFFF8, 120, titleSkip + row * buttonStep, 80, buttonHeight, 0x406B, 0); row++;
|
||||
}
|
||||
|
||||
GUI_LOL_MENU_ITEM(_gameOptions.item[row], 0xFFF7, 120, titleSkip + row * buttonStep, 80, buttonHeight, 0x406E, 0); row++;
|
||||
GUI_LOL_MENU_ITEM(_gameOptions.item[row], 0xFFF6, 120, titleSkip + row * buttonStep, 80, buttonHeight, 0x406C, 0); row++;
|
||||
GUI_LOL_MENU_ITEM(_gameOptions.item[row], 0xFFF5, 120, titleSkip + row * buttonStep, 80, buttonHeight, 0x406D, 0); row++;
|
||||
|
||||
if (_vm->gameFlags().isTalkie) {
|
||||
GUI_LOL_MENU_ITEM(_gameOptions.item[row], 0xFFF4, 120, titleSkip + row * buttonStep, 80, buttonHeight, 0x42D5, 0); row++;
|
||||
GUI_LOL_MENU_ITEM(_gameOptions.item[row], 0xFFF3, 120, titleSkip + row * buttonStep, 80, buttonHeight, 0x42D2, 0); row++;
|
||||
}
|
||||
GUI_LOL_MENU_ITEM(_gameOptions.item[row], 0x4072, 104, titleSkip + row * buttonStep + 3, 96, buttonHeight, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]);
|
||||
Button::Callback optionsMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedOptionsMenu);
|
||||
for (int i = 0; i < _gameOptions.numberOfItems; ++i)
|
||||
_gameOptions.item[i].callback = optionsMenuFunctor;
|
||||
|
||||
GUI_LOL_MENU(_audioOptions, 18, 0x42D9, 2, 1, -1, -1, -1, -1);
|
||||
GUI_LOL_MENU_ITEM(_audioOptions.item[0], 0x4072, 152, 76, 96, buttonHeight, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]);
|
||||
GUI_LOL_MENU_ITEM(_audioOptions.item[1], 3, 128, 22, 114, 14, 0x42DB, 0);
|
||||
GUI_LOL_MENU_ITEM(_audioOptions.item[2], 4, 128, 39, 114, 14, 0x42DA, 0);
|
||||
GUI_LOL_MENU_ITEM(_audioOptions.item[3], 5, 128, 56, 114, 14, 0x42DC, 0);
|
||||
Button::Callback audioMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedAudioMenu);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
_audioOptions.item[i].callback = audioMenuFunctor;
|
||||
|
||||
GUI_LOL_MENU(_deathMenu, 11, 0x4013, 0, 2, -1, -1, -1, -1);
|
||||
GUI_LOL_MENU_ITEM(_deathMenu.item[0], 0x4006, 8, 30, 104, buttonHeight, 0, 0);
|
||||
GUI_LOL_MENU_ITEM(_deathMenu.item[1], 0x4001, 176, 30, 104, buttonHeight, 0, 0);
|
||||
Button::Callback deathMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedDeathMenu);
|
||||
for (int i = 0; i < 2; ++i)
|
||||
_deathMenu.item[i].callback = deathMenuFunctor;
|
||||
|
||||
GUI_LOL_MENU(_savenameMenu, 7, 0x4053, 0, 2, -1, -1, -1, -1);
|
||||
GUI_LOL_MENU_ITEM(_savenameMenu.item[0], 0x4012, 8, 38, 72, buttonHeight, 0, _vm->_keyMap[Common::KEYCODE_RETURN]);
|
||||
GUI_LOL_MENU_ITEM(_savenameMenu.item[1], 0x4011, 176, 38, 72, buttonHeight, 0, _vm->_keyMap[Common::KEYCODE_ESCAPE]);
|
||||
Button::Callback savenameMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedSavenameMenu);
|
||||
for (int i = 0; i < 2; ++i)
|
||||
_savenameMenu.item[i].callback = savenameMenuFunctor;
|
||||
|
||||
GUI_LOL_MENU(_choiceMenu, 11, 0, 0, 2, -1, -1, -1, -1);
|
||||
GUI_LOL_MENU_ITEM(_choiceMenu.item[0], 0x4007, 8, 30, 72, buttonHeight, 0, 0);
|
||||
GUI_LOL_MENU_ITEM(_choiceMenu.item[1], 0x4008, 208, 30, 72, buttonHeight, 0, 0);
|
||||
Button::Callback choiceMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedChoiceMenu);
|
||||
for (int i = 0; i < 2; ++i)
|
||||
_choiceMenu.item[i].callback = choiceMenuFunctor;
|
||||
}
|
||||
|
||||
const ScreenDim Screen_LoL::_screenDimTable256C[] = {
|
||||
{ 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }, // Taken from Intro
|
||||
{ 0x08, 0x48, 0x18, 0x38, 0xFE, 0x01, 0x00, 0x00 },
|
||||
{ 0x0E, 0x00, 0x16, 0x78, 0xFE, 0x01, 0x00, 0x00 },
|
||||
{ 0x0B, 0x7B, 0x1C, 0x12, 0xFE, 0xFC, 0x00, 0x00 },
|
||||
{ 0x0B, 0x7B, 0x1C, 0x2D, 0xFE, 0xFC, 0x00, 0x00 },
|
||||
{ 0x55, 0x7B, 0xE9, 0x37, 0xFE, 0xFC, 0x00, 0x00 },
|
||||
{ 0x0B, 0x8C, 0x10, 0x2B, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (4 entries)
|
||||
{ 0x04, 0x59, 0x20, 0x3C, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x05, 0x6E, 0x1E, 0x0C, 0xFE, 0x01, 0x00, 0x00 },
|
||||
{ 0x07, 0x19, 0x1A, 0x97, 0x00, 0x00, 0x00, 0x00 }, // Ingame main menu box CD version
|
||||
{ 0x03, 0x1E, 0x22, 0x8C, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x02, 0x48, 0x24, 0x34, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x0E, 0x00, 0x16, 0x78, 0xFE, 0x01, 0x00, 0x00 },
|
||||
{ 0x0D, 0xA2, 0x18, 0x0C, 0xFE, 0x01, 0x00, 0x00 },
|
||||
{ 0x0F, 0x06, 0x14, 0x6E, 0x01, 0x00, 0x00, 0x00 },
|
||||
{ 0x1A, 0xBE, 0x0A, 0x07, 0xFE, 0x01, 0x00, 0x00 },
|
||||
{ 0x07, 0x21, 0x1A, 0x85, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x03, 0x32, 0x22, 0x62, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x0B, 0x8C, 0x10, 0x33, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (5 entries, CD version only)
|
||||
{ 0x0B, 0x8C, 0x10, 0x23, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (3 entries, floppy version only)
|
||||
|
||||
{ 0x01, 0x20, 0x26, 0x80, 0xDC, 0xFD, 0x00, 0x00 }, // Credits
|
||||
{ 0x09, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x19, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x01, 0x02, 0x26, 0x14, 0x00, 0x0F, 0x0E, 0x00 },
|
||||
};
|
||||
|
||||
const ScreenDim Screen_LoL::_screenDimTableZH[] = {
|
||||
{ 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }, // Taken from Intro // Full screen // Looks good
|
||||
{ 0x08, 0x48, 0x18, 0x38, 0xFE, 0x01, 0x00, 0x00 }, // Not checked
|
||||
{ 0x0E, 0x00, 0x16, 0x78, 0xFE, 0x01, 0x00, 0x00 }, // Not checked
|
||||
{ 0x0B, 0x7B, 0x1C, 0x12, 0xFE, 0xFC, 0x00, 0x00 }, // Not checked
|
||||
{ 0x0B, 0x7B, 0x1C, 0x2D, 0xFE, 0xFC, 0x00, 0x00 }, // Not checked
|
||||
{ 0x55, 0x7B, 0xE9, 0x37, 0xFE, 0xFC, 0x00, 0x00 }, // Not checked
|
||||
{ 0x0B, 0x7B, 0x10, 0x47, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (4 entries) // Looks good
|
||||
{ 0x04, 0x59, 0x20, 0x3C, 0x00, 0x00, 0x00, 0x00 }, // Not checked
|
||||
{ 0x05, 0x6E, 0x1E, 0x0C, 0xFE, 0x01, 0x00, 0x00 }, // Not checked
|
||||
{ 0x07, 0x19, 0x1A, 0x97, 0x00, 0x00, 0x00, 0x00 }, // Ingame main menu box CD version // Unused as Chinese version is floppy
|
||||
{ 0x03, 0x1E, 0x22, 0x8C, 0x00, 0x00, 0x00, 0x00 }, // Not checked
|
||||
{ 0x02, 0x48, 0x24, 0x34, 0x00, 0x00, 0x00, 0x00 }, // Not checked
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Not checked
|
||||
{ 0x0E, 0x00, 0x16, 0x78, 0xFE, 0x01, 0x00, 0x00 }, // Not checked
|
||||
{ 0x0D, 0xA2, 0x18, 0x0C, 0xFE, 0x01, 0x00, 0x00 }, // Not checked
|
||||
{ 0x0F, 0x06, 0x14, 0x6E, 0x01, 0x00, 0x00, 0x00 }, // Not checked
|
||||
{ 0x1A, 0xBE, 0x0A, 0x07, 0xFE, 0x01, 0x00, 0x00 }, // Not checked
|
||||
{ 0x07, 0x14, 0x1A, 0xA0, 0x00, 0x00, 0x00, 0x00 }, // Ingame main menu box floppy version // Looks good
|
||||
{ 0x03, 0x32, 0x22, 0x62, 0x00, 0x00, 0x00, 0x00 }, // Not checked
|
||||
{ 0x0B, 0x8C, 0x10, 0x33, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (5 entries, CD version only) // Unused as Chinese version is floppy
|
||||
{ 0x0B, 0x82, 0x10, 0x39, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (3 entries, floppy version only) // Looks good
|
||||
|
||||
{ 0x01, 0x20, 0x26, 0x80, 0xDC, 0xFD, 0x00, 0x00 }, // Credits // Not checked
|
||||
{ 0x09, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 }, // Not checked
|
||||
{ 0x19, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 }, // Not checked
|
||||
{ 0x01, 0x02, 0x26, 0x14, 0x00, 0x0F, 0x0E, 0x00 }, // Not checked
|
||||
};
|
||||
|
||||
const ScreenDim Screen_LoL::_screenDimTable16C[] = {
|
||||
{ 0x00, 0x00, 0x28, 0xC8, 0x33, 0x44, 0x00, 0x00 }, // Taken from Intro
|
||||
{ 0x08, 0x48, 0x18, 0x38, 0x33, 0x44, 0x00, 0x00 },
|
||||
{ 0x0E, 0x00, 0x16, 0x78, 0x33, 0x44, 0x00, 0x00 },
|
||||
{ 0x0B, 0x7B, 0x1C, 0x11, 0x33, 0x11, 0x00, 0x00 },
|
||||
{ 0x0B, 0x7B, 0x1C, 0x2D, 0x33, 0x11, 0x00, 0x00 },
|
||||
{ 0x55, 0x7B, 0xE9, 0x37, 0x33, 0x11, 0x00, 0x00 },
|
||||
{ 0x0B, 0x92, 0x10, 0x2A, 0x33, 0x44, 0x00, 0x00 }, // Main menu box (4 entries)
|
||||
{ 0x04, 0x58, 0x20, 0x3C, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x05, 0x6C, 0x1E, 0x0D, 0x33, 0x44, 0x00, 0x00 },
|
||||
{ 0x07, 0x20, 0x1A, 0x86, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x03, 0x20, 0x22, 0x8C, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x02, 0x48, 0x24, 0x34, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x0E, 0x00, 0x16, 0x78, 0x33, 0x44, 0x00, 0x00 },
|
||||
{ 0x0D, 0xA2, 0x18, 0x0C, 0x33, 0x44, 0x00, 0x00 },
|
||||
{ 0x0F, 0x06, 0x14, 0x6E, 0x44, 0x00, 0x00, 0x00 },
|
||||
{ 0x1A, 0xBE, 0x0A, 0x07, 0x33, 0x44, 0x00, 0x00 },
|
||||
{ 0x07, 0x21, 0x1A, 0x85, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x03, 0x32, 0x22, 0x62, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x0B, 0x8C, 0x10, 0x33, 0x33, 0x44, 0x00, 0x00 }, // Main menu box (5 entries, not used here)
|
||||
{ 0x0B, 0x8C, 0x10, 0x23, 0x33, 0x44, 0x00, 0x00 }, // Main menu box (3 entries)
|
||||
|
||||
{ 0x01, 0x20, 0x26, 0x80, 0xDC, 0xFD, 0x00, 0x00 }, // Credits (TODO: Check this!)
|
||||
{ 0x09, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x19, 0x29, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x01, 0x02, 0x26, 0x14, 0x00, 0x0F, 0x0E, 0x00 },
|
||||
};
|
||||
|
||||
const int Screen_LoL::_screenDimTableCount = ARRAYSIZE(Screen_LoL::_screenDimTable256C);
|
||||
|
||||
const char *const LoLEngine::_languageExt[] = {
|
||||
"ENG",
|
||||
"FRE",
|
||||
"GER"
|
||||
};
|
||||
|
||||
const char *const LoLEngine::_charPreviewNamesDefault[] = {
|
||||
"Ak\'shel",
|
||||
"Michael",
|
||||
"Kieran",
|
||||
"Conrad"
|
||||
};
|
||||
|
||||
const char *const LoLEngine::_charPreviewNamesRussianFloppy[] = {
|
||||
"\x80\xAA\xE8\xA5\xAB\0",
|
||||
"\x8C\xA0\xA9\xAA\xAB\0",
|
||||
"\x8A\xA8\xE0\xA0\xAD\0",
|
||||
"\x8A\xAE\xAD\xE0\xA0\xA4\0"
|
||||
};
|
||||
|
||||
const LoLEngine::CharacterPrev LoLEngine::_charPreviews[] = {
|
||||
{ 0x060, 0x7F, { 0x0F, 0x08, 0x05 } },
|
||||
{ 0x09A, 0x7F, { 0x06, 0x0A, 0x0F } },
|
||||
{ 0x0D4, 0x7F, { 0x08, 0x06, 0x08 } },
|
||||
{ 0x10F, 0x7F, { 0x0A, 0x0C, 0x0A } }
|
||||
};
|
||||
|
||||
const uint16 LoLEngine::_charPosXPC98[] = {
|
||||
92, 152, 212, 268
|
||||
};
|
||||
|
||||
const char *const LoLEngine::_charNamesJapanese[] = {
|
||||
"\x83\x41\x83\x4E\x83\x56\x83\x46\x83\x8B\0",
|
||||
"\x83\x7D\x83\x43\x83\x50\x83\x8B\x00\x00\0",
|
||||
"\x83\x4C\x81\x5B\x83\x89\x83\x93\x00\x00\0",
|
||||
"\x83\x52\x83\x93\x83\x89\x83\x62\x83\x68\0"
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_chargenFrameTableTalkie[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04,
|
||||
0x05, 0x04, 0x03, 0x02, 0x01,
|
||||
0x00, 0x00, 0x01, 0x02, 0x03,
|
||||
0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
0x09, 0x0A, 0x0B, 0x0C, 0x0D,
|
||||
0x0E, 0x0F, 0x10, 0x11, 0x12
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_chargenFrameTableFloppy[] = {
|
||||
0, 1, 2, 3, 4, 5, 4, 3, 2,
|
||||
1, 0, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
};
|
||||
|
||||
const uint16 LoLEngine::_selectionPosTable[] = {
|
||||
0x6F, 0x00, 0x8F, 0x00, 0xAF, 0x00, 0xCF, 0x00,
|
||||
0xEF, 0x00, 0x6F, 0x20, 0x8F, 0x20, 0xAF, 0x20,
|
||||
0xCF, 0x20, 0xEF, 0x20, 0x6F, 0x40, 0x8F, 0x40,
|
||||
0xAF, 0x40, 0xCF, 0x40, 0xEF, 0x40, 0x10F, 0x00
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_selectionChar1IdxTable[] = {
|
||||
0, 0, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 0, 0, 5, 5, 5,
|
||||
5, 5, 5, 5, 0, 0, 5, 5,
|
||||
5, 5, 5
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_selectionChar2IdxTable[] = {
|
||||
1, 1, 6, 6, 1, 1, 6, 6,
|
||||
6, 6, 6, 6, 6, 1, 1, 6,
|
||||
6, 6, 1, 1, 6, 6, 6, 6,
|
||||
6, 6, 6
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_selectionChar3IdxTable[] = {
|
||||
2, 2, 7, 7, 7, 7, 2, 2,
|
||||
7, 7, 7, 7, 7, 7, 7, 2,
|
||||
2, 7, 7, 7, 7, 2, 2, 7,
|
||||
7, 7, 7
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_selectionChar4IdxTable[] = {
|
||||
3, 3, 8, 8, 8, 8, 3, 3,
|
||||
8, 8, 3, 3, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 3, 3, 8,
|
||||
8, 8, 8
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_reminderChar1IdxTable[] = {
|
||||
4, 4, 4, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_reminderChar2IdxTable[] = {
|
||||
9, 9, 9, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_reminderChar3IdxTable[] = {
|
||||
0xE, 0xE, 0xE, 0x7, 0x7, 0x7, 0x7, 0x7,
|
||||
0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
|
||||
0x7
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_reminderChar4IdxTable[] = {
|
||||
0xF, 0xF, 0xF, 0x8, 0x8, 0x8, 0x8, 0x8,
|
||||
0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
|
||||
0x8
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_selectionAnimIndexTable[] = {
|
||||
0, 5, 1, 6, 2, 7, 3, 8
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_charInfoFrameTable[] = {
|
||||
0x0, 0x7, 0x8, 0x9, 0xA, 0xB, 0xA, 0x9,
|
||||
0x8, 0x7, 0x0, 0x0, 0x7, 0x8, 0x9, 0xA,
|
||||
0xB, 0xA, 0x9, 0x8, 0x7, 0x0, 0x0, 0x7,
|
||||
0x8, 0x9, 0xA, 0xB, 0xA, 0x9, 0x8, 0x7
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_clock2Timers[] = {
|
||||
0x00, 0x10, 0x11, 0x03, 0x04, 0x50,
|
||||
0x51, 0x52, 0x08, 0x09, 0x0A
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_numClock2Timers = ARRAYSIZE(LoLEngine::_clock2Timers);
|
||||
|
||||
const int8 LoLEngine::_mapCoords[12][4] = {
|
||||
{ 0, 7, 0, -5 }, { -5, 0, 6, 0 }, { 7, 5, 7, 1 },
|
||||
{ 5, 6, 4, 6 }, { 0, 7, 0, -1 }, { -3, 0, 6, 0 },
|
||||
{ 6, 7, 6, -3 }, { -3, 5, 6, 5 }, { 1, 5, 1, 1 },
|
||||
{ 3, 1, 3, 1 }, { -1, 6, -1, -8 }, { -7, -1, 5, -1 }
|
||||
};
|
||||
|
||||
// Most of these settings won't get used in LOL, since the engine was already finished when these were introduced.
|
||||
// And it is hardly worth the time to add any usage for this, since the only significant version difference would
|
||||
// be the PC-98 16 color version. That said, I have filled all the unused parts of the struct with zeroes.
|
||||
const KyraRpgGUISettings LoLEngine::_guiSettings = {
|
||||
{ _dlgButtonPosX_Def, _dlgButtonPosY_Def, 144, 254, false, 74, 9, 2, 80, { 0, 0 }, { 0, 0 }, { 0, 0 } },
|
||||
{ 136, 251, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ { 0, 0, 0 }, { 0, 0, 0 }, 0, 0,
|
||||
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
|
||||
{ 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0 }, { 0, 0, 0 }, 0, 0, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0 }, 0,
|
||||
0, 0, 0, 0, 0, 0
|
||||
},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, { 0, 0, 0 }, 0, 0, 0, 0, 0, { 0, 0, 0 } },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0, 0, 0, 0 }, { 0, 0, 0 } }
|
||||
};
|
||||
|
||||
const KyraRpgGUISettings LoLEngine::_guiSettingsZH = {
|
||||
{ _dlgButtonPosX_Def, _dlgButtonPosY_Def, 144, 254, false, 68, 18, 2, 66, { 0, 0 }, { 0, 0 }, { 0, 0 } },
|
||||
{ 136, 251, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ { 0, 0, 0 }, { 0, 0, 0 }, 0, 0,
|
||||
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
|
||||
{ 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0 }, { 0, 0, 0 }, 0, 0, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0 }, 0,
|
||||
0, 0, 0, 0, 0, 0
|
||||
},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, { 0, 0, 0 }, 0, 0, 0, 0, 0, { 0, 0, 0 } },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0, 0, 0, 0 }, { 0, 0, 0 } }
|
||||
};
|
||||
|
||||
const MistOfDoomAnimData LoLEngine::_mistAnimData[] = {
|
||||
{ 0, 7, 7, 13, 155 },
|
||||
{ 0, 16, 16, 17, 155 },
|
||||
{ 0, 24, 24, 24, 174 },
|
||||
{ 0, 19, 19, 19, 174 },
|
||||
{ 0, 16, 16, 17, 175 },
|
||||
};
|
||||
|
||||
const char *const LoLEngine::_outroShapeFileTable[] = {
|
||||
"AMAZON.SHP", "ARCHRSLG.SHP", "AVIANWRM.SHP", "BANDIT.SHP", "BOAR.SHP", "CABAL.SHP",
|
||||
"GUARD.SHP", "HAG.SHP", "HORNET.SHP", "HURZELL.SHP", "IRONGRZR.SHP", "KNOWLES.SHP",
|
||||
"LIZARD.SHP", "MANTHA.SHP", "MINOTAUR.SHP", "MORIBUND.SHP", "ORC.SHP", "ORCLDR.SHP",
|
||||
"PENTROG.SHP", "RATMAN.SHP", "ROCKLING.SHP", "SCAVNGR.SHP", "STARK.SHP",
|
||||
"SWAMPCIT.SHP", "SWAMPMON.SHP", "THUG.SHP", "VIPER.SHP", "XEOB.SHP"
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_outroFrameTable[] = {
|
||||
0, 0, 0, 0, 0, 1, 2, 3,
|
||||
0, 1, 2, 3, 8, 9, 10, 11,
|
||||
8, 9, 10, 11, 4, 5, 6, 7
|
||||
};
|
||||
|
||||
const int16 LoLEngine::_outroRightMonsterPos[] = {
|
||||
205, 55, 205, 55, 205, 55, 205, 55,
|
||||
205, 56, 207, 57, 208, 58, 210, 59,
|
||||
213, 60, 216, 61, 220, 61, 225, 61,
|
||||
230, 61, 235, 61, 240, 61, 240, 61,
|
||||
240, 61, 240, 61, 240, 61, 240, 61,
|
||||
240, 61, 265, 61, 290, 61, 315, 61
|
||||
};
|
||||
|
||||
const int16 LoLEngine::_outroLeftMonsterPos[] = {
|
||||
92, 55, 92, 55, 92, 55, 92, 55,
|
||||
92, 56, 90, 57, 85, 58, 77, 59,
|
||||
67, 60, 57, 61, 47, 61, 35, 61,
|
||||
35, 61, 35, 61, 35, 61, 35, 61,
|
||||
35, 61, 35, 61, 35, 61, 35, 61,
|
||||
35, 61, 10, 61, -20, 61, -45, 61
|
||||
};
|
||||
|
||||
const int16 LoLEngine::_outroRightDoorPos[] = {
|
||||
200, 41, 200, 29, 200, 17, 200, 5,
|
||||
200, -7, 200, -7, 200, -7, 200, -7,
|
||||
200, 5, 200, 17, 200, 29, 200, 41,
|
||||
200, 41, 200, 41, 200, 41, 200, 41,
|
||||
200, 41, 200, 41, 200, 41, 200, 41,
|
||||
200, 41, 200, 41, 200, 41, 200, 41
|
||||
};
|
||||
|
||||
const int16 LoLEngine::_outroLeftDoorPos[] = {
|
||||
72, 41, 72, 29, 72, 17, 72, 5,
|
||||
72, -7, 72, -7, 72, -7, 72, -7,
|
||||
72, 5, 72, 17, 72, 29, 72, 41,
|
||||
72, 41, 72, 41, 72, 41, 72, 41,
|
||||
72, 41, 72, 41, 72, 41, 72, 41,
|
||||
72, 41, 72, 41, 72, 41, 72, 41
|
||||
};
|
||||
|
||||
const int LoLEngine::_outroMonsterScaleTableX[] = {
|
||||
0x050, 0x050, 0x050, 0x050, 0x050, 0x05D, 0x070, 0x085,
|
||||
0x0A0, 0x0C0, 0x0E2, 0x100, 0x100, 0x100, 0x100, 0x100,
|
||||
0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100
|
||||
};
|
||||
|
||||
const int LoLEngine::_outroMonsterScaleTableY[] = {
|
||||
0x04C, 0x04C, 0x04C, 0x04C, 0x04C, 0x059, 0x06B, 0x080,
|
||||
0x099, 0x0B8, 0x0D9, 0x100, 0x100, 0x100, 0x100, 0x100,
|
||||
0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100
|
||||
};
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif
|
||||
83
engines/kyra/resource/staticres_rpg.cpp
Normal file
83
engines/kyra/resource/staticres_rpg.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/* 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 "kyra/resource/resource.h"
|
||||
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
#if defined(ENABLE_EOB) || defined(ENABLE_LOL)
|
||||
const uint32 *StaticResource::loadRawDataBe32(int id, int &entries) {
|
||||
return (const uint32 *)getData(id, kRawDataBe32, entries);
|
||||
}
|
||||
|
||||
bool StaticResource::loadRawDataBe32(Common::SeekableReadStream &stream, void *&ptr, int &size) {
|
||||
size = stream.size() >> 2;
|
||||
|
||||
uint32 *r = new uint32[size];
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
r[i] = stream.readUint32BE();
|
||||
|
||||
ptr = r;
|
||||
return true;
|
||||
}
|
||||
|
||||
void StaticResource::freeRawDataBe32(void *&ptr, int &size) {
|
||||
uint32 *data = (uint32 *)ptr;
|
||||
delete[] data;
|
||||
ptr = 0;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
const uint8 KyraRpgEngine::_dropItemDirIndex[] = { 0, 1, 2, 3, 1, 3, 0, 2, 3, 2, 1, 0, 2, 0, 3, 1 };
|
||||
|
||||
const uint16 KyraRpgEngine::_vmpOffsetsDefault[9] = { 102, 97, 129, 117, 81, 159, 45, 239, 0 };
|
||||
|
||||
const uint16 KyraRpgEngine::_vmpOffsetsSegaCD[9] = { 0, 15, 20, 50, 62, 78, 158, 194, 386 };
|
||||
|
||||
const uint16 KyraRpgEngine::_dlgButtonPosX_Def[14] = { 59, 166, 4, 112, 220, 4, 112, 220, 4, 112, 220, 4, 112, 220 };
|
||||
|
||||
const uint8 KyraRpgEngine::_dlgButtonPosY_Def[14] = { 0, 0, 0, 0, 0, 12, 12, 12, 24, 24, 24, 36, 36, 36 };
|
||||
|
||||
void KyraRpgEngine::initStaticResource() {
|
||||
int temp;
|
||||
_dscShapeX = (const int16 *)_staticres->loadRawDataBe16(kRpgCommonDscX, temp);
|
||||
_dscShapeIndex = (const int8 *)_staticres->loadRawData(kRpgCommonDscShapeIndex, temp);
|
||||
_dscTileIndex = _staticres->loadRawData(kRpgCommonDscTileIndex, temp);
|
||||
_dscDim1 = (const int8 *)_staticres->loadRawData(kRpgCommonDscDimData1, temp);
|
||||
_dscDim2 = (const int8 *)_staticres->loadRawData(kRpgCommonDscDimData2, temp);
|
||||
_dscDoorScaleOffs = _staticres->loadRawData(kRpgCommonDscDoorScaleOffs, temp);
|
||||
_dscBlockMap = _staticres->loadRawData(kRpgCommonDscBlockMap, temp);
|
||||
_dscBlockIndex = (const int8 *)_staticres->loadRawData(kRpgCommonDscBlockIndex, temp);
|
||||
_dscDimMap = _staticres->loadRawData(kRpgCommonDscDimMap, temp);
|
||||
_dscDoorShpIndex = _staticres->loadRawData(kRpgCommonDscDoorShapeIndex, _dscDoorShpIndexSize);
|
||||
_dscDoorY2 = _staticres->loadRawData(kRpgCommonDscDoorY2, temp);
|
||||
_dscDoorFrameY1 = _staticres->loadRawData(kRpgCommonDscDoorFrameY1, temp);
|
||||
_dscDoorFrameY2 = _staticres->loadRawData(kRpgCommonDscDoorFrameY2, temp);
|
||||
_dscDoorFrameIndex1 = _staticres->loadRawData(kRpgCommonDscDoorFrameIndex1, temp);
|
||||
_dscDoorFrameIndex2 = _staticres->loadRawData(kRpgCommonDscDoorFrameIndex2, temp);
|
||||
_moreStrings = _staticres->loadStrings(kRpgCommonMoreStrings, temp);
|
||||
}
|
||||
|
||||
#endif // (ENABLE_EOB || ENABLE_LOL)
|
||||
|
||||
} // End of namespace Kyra
|
||||
Reference in New Issue
Block a user