WAGE: Implement reading of all entities. This completes the world loading.

Signed-off-by: Eugene Sandulenko <sev@scummvm.org>
This commit is contained in:
Eugene Sandulenko 2010-01-11 21:30:48 +02:00
parent add5bba03f
commit 406a05aec1
6 changed files with 188 additions and 28 deletions

View File

@ -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);

View File

@ -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() {

View File

@ -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

View File

@ -92,7 +92,7 @@ public:
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 @@ public:
SHIELD_ARMOR = 2
};
Chr(String name, byte *data) {}
Chr(String name, byte *data, int dataSize);
int _index;
String _initialScene;
@ -249,7 +249,7 @@ public:
class Weapon {
public:
int _accuracy;
uint _accuracy;
String _operativeVerb;
int _type;
int _damage;
@ -268,7 +268,7 @@ public:
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 @@ public:
public:
int _index;
bool _namePlural;
int _value;
uint _value;
int _attackType;
int _numberOfUses;
bool _returnToRandomScene;
@ -353,7 +353,7 @@ public:
Common::List<Chr> _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;

View File

@ -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);
}

View File

@ -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