feat: Add support for MOD files (lip sync, game saves)

This commit is contained in:
Vsevolod Kremianskii 2020-10-25 13:53:34 +07:00
parent 82cf6e3384
commit 6465566b32
5 changed files with 27 additions and 3 deletions

View file

@ -28,12 +28,14 @@ namespace reone {
namespace resource { namespace resource {
static const int kSignatureSize = 8; static const int kSignatureSize = 8;
static const char kSignature[] = "ERF V1.0"; static const char kSignatureErf[] = "ERF V1.0";
static const char kSignatureMod[] = "MOD V1.0";
ErfFile::ErfFile() : BinaryFile(kSignatureSize, kSignature) { ErfFile::ErfFile() : BinaryFile(0, nullptr) {
} }
void ErfFile::doLoad() { void ErfFile::doLoad() {
checkSignature();
ignore(8); ignore(8);
_entryCount = readUint32(); _entryCount = readUint32();
@ -47,6 +49,22 @@ void ErfFile::doLoad() {
loadResources(); loadResources();
} }
void ErfFile::checkSignature() {
if (_size < kSignatureSize) {
throw runtime_error("Invalid binary file size");
}
char buf[kSignatureSize];
_in->read(buf, kSignatureSize);
bool erf = strncmp(buf, kSignatureErf, kSignatureSize) == 0;
if (!erf) {
bool mod = strncmp(buf, kSignatureMod, kSignatureSize) == 0;
if (!mod) {
throw runtime_error("Invalid ERF file signature");
}
}
}
void ErfFile::loadKeys() { void ErfFile::loadKeys() {
_keys.reserve(_entryCount); _keys.reserve(_entryCount);
seek(_keysOffset); seek(_keysOffset);

View file

@ -54,6 +54,8 @@ private:
std::vector<Resource> _resources; std::vector<Resource> _resources;
void doLoad() override; void doLoad() override;
void checkSignature();
void loadKeys(); void loadKeys();
Key readKey(); Key readKey();
void loadResources(); void loadResources();

View file

@ -34,6 +34,7 @@ enum class GameVersion {
enum class ResourceType : uint16_t { enum class ResourceType : uint16_t {
Invalid = 0xffff, Invalid = 0xffff,
Inventory = 0,
Bmp = 1, Bmp = 1,
Tga = 3, Tga = 3,
Wav = 4, Wav = 4,
@ -73,6 +74,7 @@ enum class ResourceType : uint16_t {
DoorWalkmesh = 2052, DoorWalkmesh = 2052,
PlaceableWalkmesh = 2053, PlaceableWalkmesh = 2053,
Journal = 2056, Journal = 2056,
Mod = 2057,
WaypointBlueprint = 2058, WaypointBlueprint = 2058,
SoundSet = 2060, SoundSet = 2060,
ScriptDebugger = 2064, ScriptDebugger = 2064,

View file

@ -30,6 +30,7 @@ namespace reone {
namespace resource { namespace resource {
static map<ResourceType, string> g_extByType = { static map<ResourceType, string> g_extByType = {
{ ResourceType::Inventory, "inv" },
{ ResourceType::Bmp, "bmp" }, { ResourceType::Bmp, "bmp" },
{ ResourceType::Tga, "tga" }, { ResourceType::Tga, "tga" },
{ ResourceType::Wav, "wav" }, { ResourceType::Wav, "wav" },
@ -69,6 +70,7 @@ static map<ResourceType, string> g_extByType = {
{ ResourceType::DoorWalkmesh, "dwk" }, { ResourceType::DoorWalkmesh, "dwk" },
{ ResourceType::PlaceableWalkmesh, "pwk" }, { ResourceType::PlaceableWalkmesh, "pwk" },
{ ResourceType::Journal, "jrl" }, { ResourceType::Journal, "jrl" },
{ ResourceType::Mod, "mod" },
{ ResourceType::WaypointBlueprint, "utw" }, { ResourceType::WaypointBlueprint, "utw" },
{ ResourceType::SoundSet, "ssf" }, { ResourceType::SoundSet, "ssf" },
{ ResourceType::ScriptDebugger, "ndb" }, { ResourceType::ScriptDebugger, "ndb" },

View file

@ -49,7 +49,7 @@ unique_ptr<Tool> getToolByPath(GameVersion version, const fs::path &path) {
return make_unique<KeyTool>(); return make_unique<KeyTool>();
} else if (ext == ".bif") { } else if (ext == ".bif") {
return make_unique<BifTool>(); return make_unique<BifTool>();
} else if (ext == ".erf") { } else if (ext == ".erf" || ext == ".mod" || ext == ".sav") {
return make_unique<ErfTool>(); return make_unique<ErfTool>();
} else if (ext == ".rim") { } else if (ext == ".rim") {
return make_unique<RimTool>(); return make_unique<RimTool>();