diff --git a/engines/wage/design.cpp b/engines/wage/design.cpp index ce9063c2dee9..df78247b8a3c 100644 --- a/engines/wage/design.cpp +++ b/engines/wage/design.cpp @@ -28,8 +28,8 @@ namespace Wage { -Design::Design(byte *data) { - int len = READ_UINT16(data); +Design::Design(byte *data, int dataSize) { + int len = READ_BE_UINT16(data); _data = (byte *)malloc(len); memcpy(_data, data, len); diff --git a/engines/wage/design.h b/engines/wage/design.h index 2956f841c0da..49f8487adcf6 100644 --- a/engines/wage/design.h +++ b/engines/wage/design.h @@ -32,11 +32,11 @@ namespace Wage { class Design { public: - Design(byte *data); + Design(byte *data, int size); ~Design(); - void setBounds(Common::Rect bounds) { - _bounds = new Common::Rect(bounds); + void setBounds(Common::Rect *bounds) { + _bounds = new Common::Rect(*bounds); } Common::Rect *getBounds() { diff --git a/engines/wage/entities.cpp b/engines/wage/entities.cpp index ef446a957286..c7336b75feb4 100644 --- a/engines/wage/entities.cpp +++ b/engines/wage/entities.cpp @@ -27,15 +27,155 @@ #include "wage/entities.h" #include "wage/design.h" +#include "common/stream.h" + namespace Wage { -void Designed::setDesignBounds(Common::Rect bounds) { - _designBounds = new Common::Rect(bounds); +void Designed::setDesignBounds(Common::Rect *bounds) { + _designBounds = new Common::Rect(*bounds); _design->setBounds(bounds); } -Scene::Scene(String name, byte *data) { +Scene::Scene(String name, byte *data, int dataSize) { + _name = name; + _design = new Design(data, dataSize); + + Common::MemoryReadStream in(data, dataSize); + + in.skip(in.readUint16BE() - 2); // Skip design. + setDesignBounds(readRect(in)); + _worldY = in.readSint16BE(); + _worldX = in.readSint16BE(); + _blocked[Scene::NORTH] = (in.readByte() != 0); + _blocked[Scene::SOUTH] = (in.readByte() != 0); + _blocked[Scene::EAST] = (in.readByte() != 0); + _blocked[Scene::WEST] = (in.readByte() != 0); + _soundFrequency = in.readSint16BE(); + _soundType = in.readByte(); + in.readByte(); // unknown + _messages[Scene::NORTH] = readPascalString(in); + _messages[Scene::SOUTH] = readPascalString(in); + _messages[Scene::EAST] = readPascalString(in); + _messages[Scene::WEST] = readPascalString(in); + _soundName = readPascalString(in); } +Obj::Obj(String name, byte *data, int dataSize) : _currentOwner(NULL), _currentScene(NULL) { + _name = name; + _design = new Design(data, dataSize); + + Common::MemoryReadStream in(data, dataSize); + + in.skip(in.readSint16BE() - 2); // Skip design. + setDesignBounds(readRect(in)); + + int16 namePlural = in.readSint16BE(); + + if (namePlural == 256) + _namePlural = true; // TODO: other flags? + else if (namePlural == 0) + _namePlural = false; + else + error("Obj <%s> had weird namePlural set", name.c_str()); + + if (in.readSint16BE() != 0) + error("Obj <%s> had short set", name.c_str()); + + if (in.readByte() != 0) + error("Obj <%s> had byte set", name.c_str()); + + _accuracy = in.readByte(); + _value = in.readByte(); + _type = in.readSByte(); + _damage = in.readByte(); + _attackType = in.readSByte(); + _numberOfUses = in.readSint16BE(); + int16 returnTo = in.readSint16BE(); + if (returnTo == 256) // TODO any other possibilities? + _returnToRandomScene = true; + else if (returnTo == 0) + _returnToRandomScene = false; + else + error("Obj <%s> had weird returnTo set", name.c_str()); + + _sceneOrOwner = readPascalString(in); + _clickMessage = readPascalString(in); + _operativeVerb = readPascalString(in); + _failureMessage = readPascalString(in); + _useMessage = readPascalString(in); + _sound = readPascalString(in); +} + +Chr::Chr(String name, byte *data, int dataSize) { + _name = name; + _design = new Design(data, dataSize); + + Common::MemoryReadStream in(data, dataSize); + + in.skip(in.readSint16BE() - 2); // Skip design. + setDesignBounds(readRect(in)); + + _physicalStrength = in.readByte(); + _physicalHp = in.readByte(); + _naturalArmor = in.readByte(); + _physicalAccuracy = in.readByte(); + + _spiritualStength = in.readByte(); + _spiritialHp = in.readByte(); + _resistanceToMagic = in.readByte(); + _spiritualAccuracy = in.readByte(); + + _runningSpeed = in.readByte(); + _rejectsOffers = in.readByte(); + _followsOpponent = in.readByte(); + + in.readSByte(); // TODO: ??? + in.readSint32BE(); // TODO: ??? + + _weaponDamage1 = in.readByte(); + _weaponDamage2 = in.readByte(); + + in.readSByte(); // TODO: ??? + + if (in.readSByte() == 1) + _playerCharacter = true; + _maximumCarriedObjects = in.readByte(); + _returnTo = in.readSByte(); + + _winningWeapons = in.readByte(); + _winningMagic = in.readByte(); + _winningRun = in.readByte(); + _winningOffer = in.readByte(); + _losingWeapons = in.readByte(); + _losingMagic = in.readByte(); + _losingRun = in.readByte(); + _losingOffer = in.readByte(); + + _gender = in.readSByte(); + if (in.readSByte() == 1) + _nameProperNoun = true; + + _initialScene = readPascalString(in); + _nativeWeapon1 = readPascalString(in); + _operativeVerb1 = readPascalString(in); + _nativeWeapon2 = readPascalString(in); + _operativeVerb2 = readPascalString(in); + + _initialComment = readPascalString(in); + _scoresHitComment = readPascalString(in); + _receivesHitComment = readPascalString(in); + _makesOfferComment = readPascalString(in); + _rejectsOfferComment = readPascalString(in); + _acceptsOfferComment = readPascalString(in); + _dyingWords = readPascalString(in); + + _initialSound = readPascalString(in); + _scoresHitSound = readPascalString(in); + _receivesHitSound = readPascalString(in); + _dyingSound = readPascalString(in); + + _weaponSound1 = readPascalString(in); + _weaponSound2 = readPascalString(in); +} } // End of namespace Wage diff --git a/engines/wage/entities.h b/engines/wage/entities.h index 834ee82cbdfe..07ecbd85802c 100644 --- a/engines/wage/entities.h +++ b/engines/wage/entities.h @@ -92,7 +92,7 @@ class Designed { return _designBounds == NULL ? NULL : new Common::Rect(*_designBounds); } - void setDesignBounds(Common::Rect bounds); + void setDesignBounds(Common::Rect *bounds); }; class Chr : public Designed { @@ -115,7 +115,7 @@ class Chr : public Designed { SHIELD_ARMOR = 2 }; - Chr(String name, byte *data) {} + Chr(String name, byte *data, int dataSize); int _index; String _initialScene; @@ -249,7 +249,7 @@ class Chr : public Designed { class Weapon { public: - int _accuracy; + uint _accuracy; String _operativeVerb; int _type; int _damage; @@ -268,7 +268,7 @@ class Weapon { class Obj : public Weapon, public Designed { public: Obj() : _currentOwner(NULL), _currentScene(NULL) {} - Obj(String name, byte *data) : _currentOwner(NULL), _currentScene(NULL) {} + Obj(String name, byte *data, int dataSize); enum ObjectTypes { REGULAR_WEAPON = 1, @@ -295,7 +295,7 @@ class Obj : public Weapon, public Designed { public: int _index; bool _namePlural; - int _value; + uint _value; int _attackType; int _numberOfUses; bool _returnToRandomScene; @@ -353,7 +353,7 @@ class Scene : public Designed { Common::List _chrs; Scene() {} - Scene(String name, byte *data); + Scene(String name, byte *data, int dataSize); Common::Rect *getTextBounds() { return _textBounds == NULL ? NULL : new Common::Rect(*_textBounds); @@ -415,7 +415,7 @@ taliesin(24):Wingdings(Decorative) class Sound { public: - Sound(byte *data) : _data(data) {} + Sound(String name, byte *data, int dataSize) : _name(name), _data(data) {} ~Sound() { free(_data); } String _name; diff --git a/engines/wage/util.cpp b/engines/wage/util.cpp index ab36582c5bfa..d38256193a69 100644 --- a/engines/wage/util.cpp +++ b/engines/wage/util.cpp @@ -57,10 +57,10 @@ Common::String readPascalString(Common::SeekableReadStream &in) { Common::Rect *readRect(Common::SeekableReadStream &in) { int x1, y1, x2, y2; - y1 = in.readUint16LE(); - x1 = in.readUint16LE(); - y2 = in.readUint16LE() + 4; - x2 = in.readUint16LE() + 4; + y1 = in.readUint16BE(); + x1 = in.readUint16BE(); + y2 = in.readUint16BE() + 4; + x2 = in.readUint16BE() + 4; return new Common::Rect(x1, y1, x2, y2); } diff --git a/engines/wage/world.cpp b/engines/wage/world.cpp index 23684e458cd2..0e3850c93035 100644 --- a/engines/wage/world.cpp +++ b/engines/wage/world.cpp @@ -83,7 +83,7 @@ bool World::loadWorld(MacResManager *resMan) { resArray = resMan->getResIDArray("ASCN"); for (iter = resArray.begin(); iter != resArray.end(); ++iter) { res = resMan->getResource("ASCN", *iter, &resSize); - Scene *scene = new Scene(resMan->getResName("ASCN", *iter), res); + Scene *scene = new Scene(resMan->getResName("ASCN", *iter), res, resSize); res = resMan->getResource("ACOD", *iter, &resSize); if (res != NULL) @@ -93,8 +93,8 @@ bool World::loadWorld(MacResManager *resMan) { if (res != NULL) { Common::MemoryReadStream readT(res, resSize); scene->_textBounds = readRect(readT); - scene->_fontType = readT.readUint16LE(); - scene->_fontSize = readT.readUint16LE(); + scene->_fontType = readT.readUint16BE(); + scene->_fontSize = readT.readUint16BE(); for (int i = 12; i < resSize; i++) if (res[i] == 0x0d) @@ -111,14 +111,14 @@ bool World::loadWorld(MacResManager *resMan) { resArray = resMan->getResIDArray("AOBJ"); for (iter = resArray.begin(); iter != resArray.end(); ++iter) { res = resMan->getResource("AOBJ", *iter, &resSize); - addObj(new Obj(resMan->getResName("AOBJ", *iter), res)); + addObj(new Obj(resMan->getResName("AOBJ", *iter), res, resSize)); } // Load Characters resArray = resMan->getResIDArray("ACHR"); for (iter = resArray.begin(); iter != resArray.end(); ++iter) { res = resMan->getResource("ACHR", *iter, &resSize); - Chr *chr = new Chr(resMan->getResName("ACHR", *iter), res); + Chr *chr = new Chr(resMan->getResName("ACHR", *iter), res, resSize); addChr(chr); // TODO: What if there's more than one player character? @@ -130,9 +130,7 @@ bool World::loadWorld(MacResManager *resMan) { resArray = resMan->getResIDArray("ASND"); for (iter = resArray.begin(); iter != resArray.end(); ++iter) { res = resMan->getResource("ASND", *iter, &resSize); - Sound *sound = new Sound(res); - sound->_name = resMan->getResName("ASND", *iter); - addSound(sound); + addSound(new Sound(resMan->getResName("ASND", *iter), res, resSize)); } if (_soundLibrary1.size() > 0) { @@ -146,7 +144,7 @@ bool World::loadWorld(MacResManager *resMan) { res = resMan->getResource("PAT#", 900, &resSize); if (res != NULL) { Common::MemoryReadStream readP(res, resSize); - int count = readP.readUint16LE(); + int count = readP.readUint16BE(); for (int i = 0; i < count; i++) { byte *pattern = (byte *)malloc(8); for (int j = 0; j < 8; j++) { @@ -162,6 +160,28 @@ bool World::loadWorld(MacResManager *resMan) { } void World::loadExternalSounds(String fname) { + Common::File in; + + in.open(fname); + if (!in.isOpen()) { + warning("Cannot load sound file <%s>", fname.c_str()); + return; + } + in.close(); + + MacResManager *resMan; + resMan = new MacResManager(fname); + + int resSize; + MacResIDArray resArray; + byte *res; + MacResIDArray::const_iterator iter; + + resArray = resMan->getResIDArray("ASND"); + for (iter = resArray.begin(); iter != resArray.end(); ++iter) { + res = resMan->getResource("ASND", *iter, &resSize); + addSound(new Sound(resMan->getResName("ASND", *iter), res, resSize)); + } } } // End of namespace Wage