Working savegame support.
Implemented also the movement of Manny's head when looking at usable items. This commit also introduces a new Object class with a ObjectPtr used for caching the resources loaded by ResourceLoader. This fixes also the lipsync regression.
This commit is contained in:
parent
24f02a74d7
commit
59dcece9ae
49 changed files with 2603 additions and 431 deletions
|
@ -30,13 +30,16 @@
|
||||||
#include "engines/grim/lipsync.h"
|
#include "engines/grim/lipsync.h"
|
||||||
#include "engines/grim/smush/smush.h"
|
#include "engines/grim/smush/smush.h"
|
||||||
#include "engines/grim/imuse/imuse.h"
|
#include "engines/grim/imuse/imuse.h"
|
||||||
|
#include "engines/grim/lua.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
int Actor::s_id = 0;
|
||||||
|
|
||||||
int g_winX1, g_winY1, g_winX2, g_winY2;
|
int g_winX1, g_winY1, g_winX2, g_winY2;
|
||||||
|
|
||||||
Actor::Actor(const char *actorName) :
|
Actor::Actor(const char *actorName) :
|
||||||
_name(actorName), _setName(""), _talkColor(255, 255, 255), _pos(0, 0, 0),
|
Object(), _name(actorName), _setName(""), _talkColor(255, 255, 255), _pos(0, 0, 0),
|
||||||
// Some actors don't set walk and turn rates, so we default the
|
// Some actors don't set walk and turn rates, so we default the
|
||||||
// _turnRate so Doug at the cat races can turn and we set the
|
// _turnRate so Doug at the cat races can turn and we set the
|
||||||
// _walkRate so Glottis at the demon beaver entrance can walk
|
// _walkRate so Glottis at the demon beaver entrance can walk
|
||||||
|
@ -48,7 +51,6 @@ Actor::Actor(const char *actorName) :
|
||||||
_turnCostume(NULL), _leftTurnChore(-1), _rightTurnChore(-1),
|
_turnCostume(NULL), _leftTurnChore(-1), _rightTurnChore(-1),
|
||||||
_lastTurnDir(0), _currTurnDir(0),
|
_lastTurnDir(0), _currTurnDir(0),
|
||||||
_mumbleCostume(NULL), _mumbleChore(-1), _sayLineText(NULL) {
|
_mumbleCostume(NULL), _mumbleChore(-1), _sayLineText(NULL) {
|
||||||
g_grim->registerActor(this);
|
|
||||||
_lookingMode = false;
|
_lookingMode = false;
|
||||||
_constrain = false;
|
_constrain = false;
|
||||||
_talkSoundName = "";
|
_talkSoundName = "";
|
||||||
|
@ -61,27 +63,338 @@ Actor::Actor(const char *actorName) :
|
||||||
_shadowArray[i].active = false;
|
_shadowArray[i].active = false;
|
||||||
_shadowArray[i].dontNegate = false;
|
_shadowArray[i].dontNegate = false;
|
||||||
_shadowArray[i].shadowMask = NULL;
|
_shadowArray[i].shadowMask = NULL;
|
||||||
|
_shadowArray[i].shadowMaskSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
_talkCostume[i] = NULL;
|
_talkCostume[i] = NULL;
|
||||||
_talkChore[i] = -1;
|
_talkChore[i] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++s_id;
|
||||||
|
_id = s_id;
|
||||||
|
|
||||||
|
g_grim->registerActor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Actor::Actor() :
|
||||||
|
Object() {
|
||||||
|
|
||||||
|
_shadowArray = new Shadow[5];
|
||||||
|
_winX1 = _winY1 = 1000;
|
||||||
|
_winX2 = _winY2 = -1000;
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
_shadowArray[i].active = false;
|
||||||
|
_shadowArray[i].dontNegate = false;
|
||||||
|
_shadowArray[i].shadowMask = NULL;
|
||||||
|
_shadowArray[i].shadowMaskSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Actor::~Actor() {
|
Actor::~Actor() {
|
||||||
clearShadowPlanes();
|
if (_shadowArray) {
|
||||||
delete[] _shadowArray;
|
clearShadowPlanes();
|
||||||
|
delete[] _shadowArray;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::saveState(SaveGame *savedState) {
|
void Actor::saveState(SaveGame *savedState) const {
|
||||||
int32 size;
|
|
||||||
|
|
||||||
// store actor name
|
// store actor name
|
||||||
size = strlen(name());
|
savedState->writeString(_name);
|
||||||
savedState->writeLESint32(size);
|
savedState->writeString(_setName);
|
||||||
savedState->write(name(), size);
|
|
||||||
|
|
||||||
|
savedState->writeColor(_talkColor);
|
||||||
|
|
||||||
|
savedState->writeVector3d(_pos);
|
||||||
|
|
||||||
|
savedState->writeFloat(_pitch);
|
||||||
|
savedState->writeFloat(_yaw);
|
||||||
|
savedState->writeFloat(_roll);
|
||||||
|
savedState->writeFloat(_walkRate);
|
||||||
|
savedState->writeFloat(_turnRate);
|
||||||
|
savedState->writeLESint32(_constrain);
|
||||||
|
savedState->writeFloat(_reflectionAngle);
|
||||||
|
savedState->writeLESint32(_visible);
|
||||||
|
savedState->writeLESint32(_lookingMode),
|
||||||
|
|
||||||
|
savedState->writeString(_talkSoundName);
|
||||||
|
|
||||||
|
if (_lipSync) {
|
||||||
|
savedState->writeLEUint32(1);
|
||||||
|
savedState->writeCharString(_lipSync->filename());
|
||||||
|
} else {
|
||||||
|
savedState->writeLEUint32(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
savedState->writeLESint32(_costumeStack.size());
|
||||||
|
for (Common::List<CostumePtr>::const_iterator i = _costumeStack.begin(); i != _costumeStack.end(); ++i) {
|
||||||
|
const CostumePtr &c = *i;
|
||||||
|
savedState->writeCharString(c->filename());
|
||||||
|
Costume *pc = c->previousCostume();
|
||||||
|
int depth = 0;
|
||||||
|
while (pc) {
|
||||||
|
++depth;
|
||||||
|
pc = pc->previousCostume();
|
||||||
|
}
|
||||||
|
savedState->writeLEUint32(depth);
|
||||||
|
pc = c->previousCostume();
|
||||||
|
for (int j = 0; j < depth; ++j) { //save the previousCostume hierarchy
|
||||||
|
savedState->writeCharString(pc->filename());
|
||||||
|
pc = pc->previousCostume();
|
||||||
|
}
|
||||||
|
c->saveState(savedState);
|
||||||
|
}
|
||||||
|
|
||||||
|
savedState->writeLESint32(_turning);
|
||||||
|
savedState->writeFloat(_destYaw);
|
||||||
|
|
||||||
|
savedState->writeLESint32(_walking);
|
||||||
|
savedState->writeVector3d(_destPos);
|
||||||
|
|
||||||
|
if (_restCostume) {
|
||||||
|
savedState->writeLEUint32(1);
|
||||||
|
savedState->writeCharString(_restCostume->filename());
|
||||||
|
} else {
|
||||||
|
savedState->writeLEUint32(0);
|
||||||
|
}
|
||||||
|
savedState->writeLESint32(_restChore);
|
||||||
|
|
||||||
|
if (_walkCostume) {
|
||||||
|
savedState->writeLEUint32(1);
|
||||||
|
savedState->writeCharString(_walkCostume->filename());
|
||||||
|
} else {
|
||||||
|
savedState->writeLEUint32(0);
|
||||||
|
}
|
||||||
|
savedState->writeLESint32(_walkChore);
|
||||||
|
savedState->writeLESint32(_walkedLast);
|
||||||
|
savedState->writeLESint32(_walkedCur);
|
||||||
|
|
||||||
|
if (_turnCostume) {
|
||||||
|
savedState->writeLEUint32(1);
|
||||||
|
savedState->writeCharString(_turnCostume->filename());
|
||||||
|
} else {
|
||||||
|
savedState->writeLEUint32(0);
|
||||||
|
}
|
||||||
|
savedState->writeLESint32(_leftTurnChore);
|
||||||
|
savedState->writeLESint32(_rightTurnChore);
|
||||||
|
savedState->writeLESint32(_lastTurnDir);
|
||||||
|
savedState->writeLESint32(_currTurnDir);
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
if (_talkCostume[i]) {
|
||||||
|
savedState->writeLEUint32(1);
|
||||||
|
savedState->writeCharString(_talkCostume[i]->filename());
|
||||||
|
} else {
|
||||||
|
savedState->writeLEUint32(0);
|
||||||
|
}
|
||||||
|
savedState->writeLESint32(_talkChore[i]);
|
||||||
|
}
|
||||||
|
savedState->writeLESint32(_talkAnim);
|
||||||
|
|
||||||
|
if (_mumbleCostume) {
|
||||||
|
savedState->writeLEUint32(1);
|
||||||
|
savedState->writeCharString(_mumbleCostume->filename());
|
||||||
|
} else {
|
||||||
|
savedState->writeLEUint32(0);
|
||||||
|
}
|
||||||
|
savedState->writeLESint32(_mumbleChore);
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
Shadow &shadow = _shadowArray[i];
|
||||||
|
savedState->writeString(shadow.name);
|
||||||
|
|
||||||
|
savedState->writeVector3d(shadow.pos);
|
||||||
|
|
||||||
|
savedState->writeLESint32(shadow.planeList.size());
|
||||||
|
for (SectorListType::iterator j = shadow.planeList.begin(); j != shadow.planeList.end(); ++j) {
|
||||||
|
Sector *sec = *j;
|
||||||
|
Scene *s = g_grim->currScene();
|
||||||
|
for (int k = 0; k < s->getSectorCount(); ++k) {
|
||||||
|
if (s->getSectorBase(k) == sec) {
|
||||||
|
savedState->writeLEUint32(k);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
savedState->writeLESint32(shadow.shadowMaskSize);
|
||||||
|
for (int j = 0; j < shadow.shadowMaskSize; ++j) {
|
||||||
|
savedState->writeByte(shadow.shadowMask[j]);
|
||||||
|
}
|
||||||
|
savedState->writeLESint32(shadow.active);
|
||||||
|
savedState->writeLESint32(shadow.dontNegate);
|
||||||
|
}
|
||||||
|
savedState->writeLESint32(_activeShadowSlot);
|
||||||
|
|
||||||
|
if (_sayLineText) {
|
||||||
|
savedState->writeLEUint32(g_grim->textObjectId(_sayLineText));
|
||||||
|
} else {
|
||||||
|
savedState->writeLEUint32(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
savedState->writeVector3d(_lookAtVector);
|
||||||
|
savedState->writeFloat(_lookAtRate);
|
||||||
|
|
||||||
|
savedState->writeLESint32(_winX1);
|
||||||
|
savedState->writeLESint32(_winY1);
|
||||||
|
savedState->writeLESint32(_winX2);
|
||||||
|
savedState->writeLESint32(_winY2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Actor::restoreState(SaveGame *savedState) {
|
||||||
|
// load actor name
|
||||||
|
_name = savedState->readString();
|
||||||
|
_setName = savedState->readString();
|
||||||
|
|
||||||
|
_talkColor = savedState->readColor();
|
||||||
|
|
||||||
|
_pos = savedState->readVector3d();
|
||||||
|
_pitch = savedState->readFloat();
|
||||||
|
_yaw = savedState->readFloat();
|
||||||
|
_roll = savedState->readFloat();
|
||||||
|
_walkRate = savedState->readFloat();
|
||||||
|
_turnRate = savedState->readFloat();
|
||||||
|
_constrain = savedState->readLESint32();
|
||||||
|
_reflectionAngle = savedState->readFloat();
|
||||||
|
_visible = savedState->readLESint32();
|
||||||
|
_lookingMode = savedState->readLESint32();
|
||||||
|
|
||||||
|
_talkSoundName = savedState->readString();
|
||||||
|
|
||||||
|
if (savedState->readLEUint32()) {
|
||||||
|
const char *fn = savedState->readCharString();
|
||||||
|
_lipSync = g_resourceloader->getLipSync(fn);
|
||||||
|
delete[] fn;
|
||||||
|
} else {
|
||||||
|
_lipSync = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 size = savedState->readLESint32();
|
||||||
|
_costumeStack.clear();
|
||||||
|
for (int32 i = 0; i < size; ++i) {
|
||||||
|
const char *fname = savedState->readCharString();
|
||||||
|
const int depth = savedState->readLEUint32();
|
||||||
|
CostumePtr pc = NULL;
|
||||||
|
if (depth > 0) { //build all the previousCostume hierarchy
|
||||||
|
const char **names = new const char*[depth];
|
||||||
|
for (int j = 0; j < depth; ++j) {
|
||||||
|
names[j] = savedState->readCharString();
|
||||||
|
}
|
||||||
|
for (int j = depth - 1; j >= 0; --j) {
|
||||||
|
pc = g_resourceloader->getCostume(names[j], pc);
|
||||||
|
}
|
||||||
|
for (int j = 0; j < depth; ++j) {
|
||||||
|
delete[] names[j];
|
||||||
|
}
|
||||||
|
delete[] names;
|
||||||
|
}
|
||||||
|
|
||||||
|
CostumePtr c = g_resourceloader->getCostume(fname, pc);
|
||||||
|
c->restoreState(savedState);
|
||||||
|
_costumeStack.push_back(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
_turning = savedState->readLESint32();
|
||||||
|
_destYaw = savedState->readFloat();
|
||||||
|
|
||||||
|
_walking = savedState->readLESint32();
|
||||||
|
_destPos = savedState->readVector3d();
|
||||||
|
|
||||||
|
if (savedState->readLEUint32()) {
|
||||||
|
const char *fname = savedState->readCharString();
|
||||||
|
_restCostume = g_resourceloader->getCostume(fname, 0);
|
||||||
|
delete[] fname;
|
||||||
|
} else {
|
||||||
|
_restCostume = NULL;
|
||||||
|
}
|
||||||
|
_restChore = savedState->readLESint32();
|
||||||
|
|
||||||
|
if (savedState->readLEUint32()) {
|
||||||
|
const char *fname = savedState->readCharString();
|
||||||
|
_walkCostume = g_resourceloader->getCostume(fname, 0);
|
||||||
|
delete[] fname;
|
||||||
|
} else {
|
||||||
|
_walkCostume = NULL;
|
||||||
|
}
|
||||||
|
_walkChore = savedState->readLESint32();
|
||||||
|
_walkedLast = savedState->readLESint32();
|
||||||
|
_walkedCur = savedState->readLESint32();
|
||||||
|
|
||||||
|
if (savedState->readLEUint32()) {
|
||||||
|
const char *fname = savedState->readCharString();
|
||||||
|
_turnCostume = g_resourceloader->getCostume(fname, 0);
|
||||||
|
delete[] fname;
|
||||||
|
} else {
|
||||||
|
_turnCostume = NULL;
|
||||||
|
}
|
||||||
|
_leftTurnChore = savedState->readLESint32();
|
||||||
|
_rightTurnChore = savedState->readLESint32();
|
||||||
|
_lastTurnDir = savedState->readLESint32();
|
||||||
|
_currTurnDir = savedState->readLESint32();
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
if (savedState->readLEUint32()) {
|
||||||
|
const char *fname = savedState->readCharString();
|
||||||
|
_talkCostume[i] = g_resourceloader->getCostume(fname, 0);
|
||||||
|
delete[] fname;
|
||||||
|
} else {
|
||||||
|
_talkCostume[i] = NULL;
|
||||||
|
}
|
||||||
|
_talkChore[i] = savedState->readLESint32();
|
||||||
|
}
|
||||||
|
_talkAnim = savedState->readLESint32();
|
||||||
|
|
||||||
|
if (savedState->readLEUint32()) {
|
||||||
|
const char *fname = savedState->readCharString();
|
||||||
|
_mumbleCostume = g_resourceloader->getCostume(fname, 0);
|
||||||
|
delete[] fname;
|
||||||
|
} else {
|
||||||
|
_mumbleCostume = NULL;
|
||||||
|
}
|
||||||
|
_mumbleChore = savedState->readLESint32();
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
Shadow &shadow = _shadowArray[i];
|
||||||
|
shadow.name = savedState->readString();
|
||||||
|
|
||||||
|
shadow.pos = savedState->readVector3d();
|
||||||
|
|
||||||
|
size = savedState->readLESint32();
|
||||||
|
shadow.planeList.clear();
|
||||||
|
for (int j = 0; j < size; ++j) {
|
||||||
|
int32 id = savedState->readLEUint32();
|
||||||
|
Sector *s = g_grim->currScene()->getSectorBase(id);
|
||||||
|
shadow.planeList.push_back(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
shadow.shadowMaskSize = savedState->readLESint32();
|
||||||
|
delete[] shadow.shadowMask;
|
||||||
|
if (shadow.shadowMaskSize > 0) {
|
||||||
|
shadow.shadowMask = new byte[shadow.shadowMaskSize];
|
||||||
|
for (int j = 0; j < shadow.shadowMaskSize; ++j) {
|
||||||
|
shadow.shadowMask[j] = savedState->readByte();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
shadow.shadowMask = NULL;
|
||||||
|
}
|
||||||
|
shadow.active = savedState->readLESint32();
|
||||||
|
shadow.dontNegate = savedState->readLESint32();
|
||||||
|
}
|
||||||
|
_activeShadowSlot = savedState->readLESint32();
|
||||||
|
|
||||||
|
_sayLineText = g_grim->textObject(savedState->readLEUint32());
|
||||||
|
|
||||||
|
_lookAtVector = savedState->readVector3d();
|
||||||
|
_lookAtRate = savedState->readFloat();
|
||||||
|
|
||||||
|
_winX1 = savedState->readLESint32();
|
||||||
|
_winY1 = savedState->readLESint32();
|
||||||
|
_winX2 = savedState->readLESint32();
|
||||||
|
_winY2 = savedState->readLESint32();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::setYaw(float yawParam) {
|
void Actor::setYaw(float yawParam) {
|
||||||
|
@ -222,7 +535,7 @@ Graphics::Vector3d Actor::puckVector() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::setRestChore(int chore, Costume *cost) {
|
void Actor::setRestChore(int chore, Costume *cost) {
|
||||||
if (_restCostume == cost && _restChore == chore)
|
if (_restCostume.object() == cost && _restChore == chore)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_restChore >= 0)
|
if (_restChore >= 0)
|
||||||
|
@ -236,7 +549,7 @@ void Actor::setRestChore(int chore, Costume *cost) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::setWalkChore(int chore, Costume *cost) {
|
void Actor::setWalkChore(int chore, Costume *cost) {
|
||||||
if (_walkCostume == cost && _walkChore == chore)
|
if (_walkCostume.object() == cost && _walkChore == chore)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_walkChore >= 0)
|
if (_walkChore >= 0)
|
||||||
|
@ -247,7 +560,7 @@ void Actor::setWalkChore(int chore, Costume *cost) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::setTurnChores(int left_chore, int right_chore, Costume *cost) {
|
void Actor::setTurnChores(int left_chore, int right_chore, Costume *cost) {
|
||||||
if (_turnCostume == cost && _leftTurnChore == left_chore &&
|
if (_turnCostume.object() == cost && _leftTurnChore == left_chore &&
|
||||||
_rightTurnChore == right_chore)
|
_rightTurnChore == right_chore)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -270,7 +583,7 @@ void Actor::setTalkChore(int index, int chore, Costume *cost) {
|
||||||
|
|
||||||
index--;
|
index--;
|
||||||
|
|
||||||
if (_talkCostume[index] == cost && _talkChore[index] == chore)
|
if (_talkCostume[index].object() == cost && _talkChore[index] == chore)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_talkChore[index] >= 0)
|
if (_talkChore[index] >= 0)
|
||||||
|
@ -353,7 +666,7 @@ void Actor::sayLine(const char *msg, const char *msgId) {
|
||||||
// For example, when reading the work order (a LIP file exists for no reason).
|
// For example, when reading the work order (a LIP file exists for no reason).
|
||||||
// Also, some lip sync files have no entries
|
// Also, some lip sync files have no entries
|
||||||
// In these cases, revert to using the mumble chore.
|
// In these cases, revert to using the mumble chore.
|
||||||
_lipSync = g_resourceloader->loadLipSync(soundLip.c_str());
|
_lipSync = g_resourceloader->getLipSync(soundLip.c_str());
|
||||||
// If there's no lip sync file then load the mumble chore if it exists
|
// If there's no lip sync file then load the mumble chore if it exists
|
||||||
// (the mumble chore doesn't exist with the cat races announcer)
|
// (the mumble chore doesn't exist with the cat races announcer)
|
||||||
if (!_lipSync && _mumbleChore != -1)
|
if (!_lipSync && _mumbleChore != -1)
|
||||||
|
@ -393,7 +706,7 @@ void Actor::sayLine(const char *msg, const char *msgId) {
|
||||||
|
|
||||||
bool Actor::talking() {
|
bool Actor::talking() {
|
||||||
// If there's no sound file then we're obviously not talking
|
// If there's no sound file then we're obviously not talking
|
||||||
if (strlen(_talkSoundName.c_str()) == 0)
|
if (strlen(_talkSoundName.c_str()) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return g_imuse->getSoundStatus(_talkSoundName.c_str());
|
return g_imuse->getSoundStatus(_talkSoundName.c_str());
|
||||||
|
@ -423,7 +736,7 @@ void Actor::shutUp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::pushCostume(const char *n) {
|
void Actor::pushCostume(const char *n) {
|
||||||
Costume *newCost = g_resourceloader->loadCostume(n, currentCostume());
|
CostumePtr newCost = g_resourceloader->getCostume(n, currentCostume());
|
||||||
|
|
||||||
newCost->setColormap(NULL);
|
newCost->setColormap(NULL);
|
||||||
_costumeStack.push_back(newCost);
|
_costumeStack.push_back(newCost);
|
||||||
|
@ -447,8 +760,8 @@ void Actor::setCostume(const char *n) {
|
||||||
|
|
||||||
void Actor::popCostume() {
|
void Actor::popCostume() {
|
||||||
if (!_costumeStack.empty()) {
|
if (!_costumeStack.empty()) {
|
||||||
freeCostumeChore(_costumeStack.back(), _restCostume, _restChore);
|
freeCostumeChore(_costumeStack.back().object(), _restCostume, _restChore);
|
||||||
freeCostumeChore(_costumeStack.back(), _walkCostume, _walkChore);
|
freeCostumeChore(_costumeStack.back().object(), _walkCostume, _walkChore);
|
||||||
|
|
||||||
if (_turnCostume == _costumeStack.back()) {
|
if (_turnCostume == _costumeStack.back()) {
|
||||||
_turnCostume = NULL;
|
_turnCostume = NULL;
|
||||||
|
@ -489,9 +802,10 @@ void Actor::setHead(int joint1, int joint2, int joint3, float maxRoll, float max
|
||||||
}
|
}
|
||||||
|
|
||||||
Costume *Actor::findCostume(const char *n) {
|
Costume *Actor::findCostume(const char *n) {
|
||||||
for (Common::List<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); ++i)
|
for (Common::List<CostumePtr>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); ++i) {
|
||||||
if (strcasecmp((*i)->filename(), n) == 0)
|
if (strcasecmp((*i)->filename(), n) == 0)
|
||||||
return *i;
|
return *i;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -541,8 +855,9 @@ void Actor::update() {
|
||||||
// It seems that we need to allow an already active turning motion to
|
// It seems that we need to allow an already active turning motion to
|
||||||
// continue or else turning actors away from barriers won't work right
|
// continue or else turning actors away from barriers won't work right
|
||||||
// _turning = false;
|
// _turning = false;
|
||||||
} else
|
} else {
|
||||||
_pos += dir * walkAmt;
|
_pos += dir * walkAmt;
|
||||||
|
}
|
||||||
|
|
||||||
_walkedCur = true;
|
_walkedCur = true;
|
||||||
}
|
}
|
||||||
|
@ -602,8 +917,9 @@ void Actor::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Common::List<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); ++i) {
|
for (Common::List<CostumePtr>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); ++i) {
|
||||||
(*i)->setPosRotate(_pos, _pitch, _yaw, _roll);
|
(*i)->setPosRotate(_pos, _pitch, _yaw, _roll);
|
||||||
|
(*i)->setLookAt(_lookAtVector);
|
||||||
(*i)->update();
|
(*i)->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,7 +932,7 @@ void Actor::draw() {
|
||||||
g_winX1 = g_winY1 = 1000;
|
g_winX1 = g_winY1 = 1000;
|
||||||
g_winX2 = g_winY2 = -1000;
|
g_winX2 = g_winY2 = -1000;
|
||||||
|
|
||||||
for (Common::List<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); ++i)
|
for (Common::List<CostumePtr>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); ++i)
|
||||||
(*i)->setupTextures();
|
(*i)->setupTextures();
|
||||||
|
|
||||||
if (!g_driver->isHardwareAccelerated() && g_grim->getFlagRefreshShadowMask()) {
|
if (!g_driver->isHardwareAccelerated() && g_grim->getFlagRefreshShadowMask()) {
|
||||||
|
@ -735,10 +1051,22 @@ void Actor::clearShadowPlanes() {
|
||||||
shadow->planeList.pop_back();
|
shadow->planeList.pop_back();
|
||||||
}
|
}
|
||||||
delete[] shadow->shadowMask;
|
delete[] shadow->shadowMask;
|
||||||
|
shadow->shadowMaskSize = 0;
|
||||||
shadow->shadowMask = NULL;
|
shadow->shadowMask = NULL;
|
||||||
shadow->active = false;
|
shadow->active = false;
|
||||||
shadow->dontNegate = false;
|
shadow->dontNegate = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Actor::inSet(const char *setName) const {
|
||||||
|
return _setName == setName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::freeCostumeChore(Costume *toFree, CostumePtr &cost, int &chore) {
|
||||||
|
if (cost.object() == toFree) {
|
||||||
|
cost = NULL;
|
||||||
|
chore = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#ifndef GRIM_ACTOR_H
|
#ifndef GRIM_ACTOR_H
|
||||||
#define GRIM_ACTOR_H
|
#define GRIM_ACTOR_H
|
||||||
|
|
||||||
|
#include "engines/grim/object.h"
|
||||||
#include "engines/grim/color.h"
|
#include "engines/grim/color.h"
|
||||||
#include "engines/grim/resource.h"
|
#include "engines/grim/resource.h"
|
||||||
#include "engines/grim/savegame.h"
|
#include "engines/grim/savegame.h"
|
||||||
|
@ -45,16 +46,20 @@ struct Shadow {
|
||||||
Graphics::Vector3d pos;
|
Graphics::Vector3d pos;
|
||||||
SectorListType planeList;
|
SectorListType planeList;
|
||||||
byte *shadowMask;
|
byte *shadowMask;
|
||||||
|
int shadowMaskSize;
|
||||||
bool active;
|
bool active;
|
||||||
bool dontNegate;
|
bool dontNegate;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Actor {
|
class Actor : public Object {
|
||||||
|
GRIM_OBJECT(Actor)
|
||||||
public:
|
public:
|
||||||
Actor(const char *name);
|
Actor(const char *name);
|
||||||
|
Actor();
|
||||||
~Actor();
|
~Actor();
|
||||||
|
|
||||||
void saveState(SaveGame *savedState);
|
void saveState(SaveGame *savedState) const;
|
||||||
|
bool restoreState(SaveGame *savedState);
|
||||||
|
|
||||||
const char *name() const { return _name.c_str(); }
|
const char *name() const { return _name.c_str(); }
|
||||||
|
|
||||||
|
@ -93,9 +98,7 @@ public:
|
||||||
float angleTo(const Actor &a) const;
|
float angleTo(const Actor &a) const;
|
||||||
float yawTo(Graphics::Vector3d p) const;
|
float yawTo(Graphics::Vector3d p) const;
|
||||||
|
|
||||||
bool inSet(const char *setName) const {
|
bool inSet(const char *setName) const;
|
||||||
return _setName == setName;
|
|
||||||
}
|
|
||||||
void walkForward();
|
void walkForward();
|
||||||
void setReflection(float angle) { _reflectionAngle = angle; }
|
void setReflection(float angle) { _reflectionAngle = angle; }
|
||||||
Graphics::Vector3d puckVector() const;
|
Graphics::Vector3d puckVector() const;
|
||||||
|
@ -168,6 +171,7 @@ public:
|
||||||
private:
|
private:
|
||||||
Common::String _name;
|
Common::String _name;
|
||||||
Common::String _setName; // The actual current set
|
Common::String _setName; // The actual current set
|
||||||
|
|
||||||
Color _talkColor;
|
Color _talkColor;
|
||||||
Graphics::Vector3d _pos;
|
Graphics::Vector3d _pos;
|
||||||
float _pitch, _yaw, _roll;
|
float _pitch, _yaw, _roll;
|
||||||
|
@ -178,8 +182,8 @@ private:
|
||||||
bool _visible;
|
bool _visible;
|
||||||
bool _lookingMode;
|
bool _lookingMode;
|
||||||
Common::String _talkSoundName;
|
Common::String _talkSoundName;
|
||||||
LipSync *_lipSync;
|
LipSyncPtr _lipSync;
|
||||||
Common::List<Costume *> _costumeStack;
|
Common::List<CostumePtr> _costumeStack;
|
||||||
|
|
||||||
// Variables for gradual turning
|
// Variables for gradual turning
|
||||||
bool _turning;
|
bool _turning;
|
||||||
|
@ -190,28 +194,28 @@ private:
|
||||||
Graphics::Vector3d _destPos;
|
Graphics::Vector3d _destPos;
|
||||||
|
|
||||||
// chores
|
// chores
|
||||||
Costume *_restCostume;
|
CostumePtr _restCostume;
|
||||||
int _restChore;
|
int _restChore;
|
||||||
|
|
||||||
Costume *_walkCostume;
|
CostumePtr _walkCostume;
|
||||||
int _walkChore;
|
int _walkChore;
|
||||||
bool _walkedLast, _walkedCur;
|
bool _walkedLast, _walkedCur;
|
||||||
|
|
||||||
Costume *_turnCostume;
|
CostumePtr _turnCostume;
|
||||||
int _leftTurnChore, _rightTurnChore;
|
int _leftTurnChore, _rightTurnChore;
|
||||||
int _lastTurnDir, _currTurnDir;
|
int _lastTurnDir, _currTurnDir;
|
||||||
|
|
||||||
Costume *_talkCostume[10];
|
CostumePtr _talkCostume[10];
|
||||||
int _talkChore[10];
|
int _talkChore[10];
|
||||||
int _talkAnim;
|
int _talkAnim;
|
||||||
|
|
||||||
Costume *_mumbleCostume;
|
CostumePtr _mumbleCostume;
|
||||||
int _mumbleChore;
|
int _mumbleChore;
|
||||||
|
|
||||||
Shadow *_shadowArray;
|
Shadow *_shadowArray;
|
||||||
int _activeShadowSlot;
|
int _activeShadowSlot;
|
||||||
|
|
||||||
static Font *_sayLineFont;
|
static FontPtr _sayLineFont;
|
||||||
TextObject *_sayLineText;
|
TextObject *_sayLineText;
|
||||||
|
|
||||||
// Validate a yaw angle then set it appropriately
|
// Validate a yaw angle then set it appropriately
|
||||||
|
@ -221,12 +225,7 @@ private:
|
||||||
return (dir > 0 ? _rightTurnChore : _leftTurnChore);
|
return (dir > 0 ? _rightTurnChore : _leftTurnChore);
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeCostumeChore(Costume *toFree, Costume *&cost, int &chore) {
|
void freeCostumeChore(Costume *toFree, CostumePtr &cost, int &chore);
|
||||||
if (cost == toFree) {
|
|
||||||
cost = NULL;
|
|
||||||
chore = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// lookAt
|
// lookAt
|
||||||
Graphics::Vector3d _lookAtVector;
|
Graphics::Vector3d _lookAtVector;
|
||||||
|
@ -234,6 +233,9 @@ private:
|
||||||
|
|
||||||
int _winX1, _winY1, _winX2, _winY2;
|
int _winX1, _winY1, _winX2, _winY2;
|
||||||
|
|
||||||
|
int _id;
|
||||||
|
static int s_id;
|
||||||
|
|
||||||
friend class GrimEngine;
|
friend class GrimEngine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,12 +28,14 @@
|
||||||
#include "engines/grim/grim.h"
|
#include "engines/grim/grim.h"
|
||||||
#include "engines/grim/bitmap.h"
|
#include "engines/grim/bitmap.h"
|
||||||
#include "engines/grim/gfx_base.h"
|
#include "engines/grim/gfx_base.h"
|
||||||
|
#include "engines/grim/savegame.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
static void decompress_codec3(const char *compressed, char *result);
|
static void decompress_codec3(const char *compressed, char *result);
|
||||||
|
|
||||||
Bitmap::Bitmap(const char *fname, const char *data, int len) {
|
Bitmap::Bitmap(const char *fname, const char *data, int len) :
|
||||||
|
Object() {
|
||||||
_fname = fname;
|
_fname = fname;
|
||||||
|
|
||||||
if (len < 8 || memcmp(data, "BM F\0\0\0", 8) != 0) {
|
if (len < 8 || memcmp(data, "BM F\0\0\0", 8) != 0) {
|
||||||
|
@ -44,19 +46,19 @@ Bitmap::Bitmap(const char *fname, const char *data, int len) {
|
||||||
strcpy(_filename, fname);
|
strcpy(_filename, fname);
|
||||||
|
|
||||||
int codec = READ_LE_UINT32(data + 8);
|
int codec = READ_LE_UINT32(data + 8);
|
||||||
// _paletteIncluded = READ_LE_UINT32(data + 12);
|
// _paletteIncluded = READ_LE_UINT32(data + 12);
|
||||||
_numImages = READ_LE_UINT32(data + 16);
|
_numImages = READ_LE_UINT32(data + 16);
|
||||||
_x = READ_LE_UINT32(data + 20);
|
_x = READ_LE_UINT32(data + 20);
|
||||||
_y = READ_LE_UINT32(data + 24);
|
_y = READ_LE_UINT32(data + 24);
|
||||||
// _transparentColor = READ_LE_UINT32(data + 28);
|
// _transparentColor = READ_LE_UINT32(data + 28);
|
||||||
_format = READ_LE_UINT32(data + 32);
|
_format = READ_LE_UINT32(data + 32);
|
||||||
// _numBits = READ_LE_UINT32(data + 36);
|
// _numBits = READ_LE_UINT32(data + 36);
|
||||||
// _blueBits = READ_LE_UINT32(data + 40);
|
// _blueBits = READ_LE_UINT32(data + 40);
|
||||||
// _greenBits = READ_LE_UINT32(data + 44);
|
// _greenBits = READ_LE_UINT32(data + 44);
|
||||||
// _redBits = READ_LE_UINT32(data + 48);
|
// _redBits = READ_LE_UINT32(data + 48);
|
||||||
// _blueShift = READ_LE_UINT32(data + 52);
|
// _blueShift = READ_LE_UINT32(data + 52);
|
||||||
// _greenShift = READ_LE_UINT32(data + 56);
|
// _greenShift = READ_LE_UINT32(data + 56);
|
||||||
// _redShift = READ_LE_UINT32(data + 60);
|
// _redShift = READ_LE_UINT32(data + 60);
|
||||||
_width = READ_LE_UINT32(data + 128);
|
_width = READ_LE_UINT32(data + 128);
|
||||||
_height = READ_LE_UINT32(data + 132);
|
_height = READ_LE_UINT32(data + 132);
|
||||||
_currImage = 1;
|
_currImage = 1;
|
||||||
|
@ -85,7 +87,7 @@ Bitmap::Bitmap(const char *fname, const char *data, int len) {
|
||||||
g_driver->createBitmap(this);
|
g_driver->createBitmap(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap::Bitmap(const char *data, int w, int h, const char *fname) {
|
Bitmap::Bitmap(const char *data, int w, int h, const char *fname) : Object() {
|
||||||
_fname = fname;
|
_fname = fname;
|
||||||
if (gDebugLevel == DEBUG_BITMAPS || gDebugLevel == DEBUG_NORMAL || gDebugLevel == DEBUG_ALL)
|
if (gDebugLevel == DEBUG_BITMAPS || gDebugLevel == DEBUG_NORMAL || gDebugLevel == DEBUG_ALL)
|
||||||
printf("New bitmap loaded: %s\n", fname);
|
printf("New bitmap loaded: %s\n", fname);
|
||||||
|
@ -121,8 +123,11 @@ Bitmap::~Bitmap() {
|
||||||
|
|
||||||
delete[] _data;
|
delete[] _data;
|
||||||
_data = NULL;
|
_data = NULL;
|
||||||
|
|
||||||
|
g_driver->destroyBitmap(this);
|
||||||
}
|
}
|
||||||
g_driver->destroyBitmap(this);
|
if (g_resourceloader)
|
||||||
|
g_resourceloader->uncacheBitmap(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_BIT do { bit = bitstr_value & 1; \
|
#define GET_BIT do { bit = bitstr_value & 1; \
|
||||||
|
|
|
@ -27,14 +27,17 @@
|
||||||
#define GRIM_BITMAP_H
|
#define GRIM_BITMAP_H
|
||||||
|
|
||||||
#include "engines/grim/resource.h"
|
#include "engines/grim/resource.h"
|
||||||
|
#include "engines/grim/object.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
class Bitmap {
|
class Bitmap : public Object {
|
||||||
|
GRIM_OBJECT(Bitmap)
|
||||||
public:
|
public:
|
||||||
// Construct a bitmap from the given data.
|
// Construct a bitmap from the given data.
|
||||||
Bitmap(const char *filename, const char *data, int len);
|
Bitmap(const char *filename, const char *data, int len);
|
||||||
Bitmap(const char *data, int width, int height, const char *filename);
|
Bitmap(const char *data, int width, int height, const char *filename);
|
||||||
|
Bitmap() : Object() { _data = 0; }
|
||||||
|
|
||||||
const char *filename() const { return _fname.c_str(); }
|
const char *filename() const { return _fname.c_str(); }
|
||||||
|
|
||||||
|
@ -57,7 +60,7 @@ public:
|
||||||
|
|
||||||
char *getFilename() { return _filename; }
|
char *getFilename() { return _filename; }
|
||||||
|
|
||||||
~Bitmap();
|
virtual ~Bitmap();
|
||||||
|
|
||||||
//private:
|
//private:
|
||||||
Common::String _fname;
|
Common::String _fname;
|
||||||
|
|
|
@ -27,10 +27,13 @@
|
||||||
#define GRIM_COLOR_H
|
#define GRIM_COLOR_H
|
||||||
|
|
||||||
#include "common/sys.h"
|
#include "common/sys.h"
|
||||||
|
#include "engines/grim/savegame.h"
|
||||||
|
#include "engines/grim/object.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
class Color {
|
class Color : public Object {
|
||||||
|
GRIM_OBJECT(Color)
|
||||||
public:
|
public:
|
||||||
byte _vals[3];
|
byte _vals[3];
|
||||||
|
|
||||||
|
@ -57,6 +60,20 @@ public:
|
||||||
_vals[0] = c->_vals[0]; _vals[1] = c->_vals[1]; _vals[2] = c->_vals[2];
|
_vals[0] = c->_vals[0]; _vals[1] = c->_vals[1]; _vals[2] = c->_vals[2];
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void saveState(SaveGame *state) const {
|
||||||
|
state->writeByte(_vals[0]);
|
||||||
|
state->writeByte(_vals[1]);
|
||||||
|
state->writeByte(_vals[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool restoreState(SaveGame *state) {
|
||||||
|
_vals[0] = state->readByte();
|
||||||
|
_vals[1] = state->readByte();
|
||||||
|
_vals[2] = state->readByte();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -29,23 +29,39 @@
|
||||||
#include "common/endian.h"
|
#include "common/endian.h"
|
||||||
|
|
||||||
#include "engines/grim/resource.h"
|
#include "engines/grim/resource.h"
|
||||||
|
#include "engines/grim/object.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
class CMap {
|
class CMap : public Object {
|
||||||
|
GRIM_OBJECT(ColorMap)
|
||||||
public:
|
public:
|
||||||
// Load a colormap from the given data.
|
// Load a colormap from the given data.
|
||||||
CMap(const char *fileName, const char *data, int len) {
|
CMap(const char *fileName, const char *data, int len) :
|
||||||
|
Object() {
|
||||||
_fname = fileName;
|
_fname = fileName;
|
||||||
if (len < 4 || READ_BE_UINT32(data) != MKID_BE('CMP '))
|
if (len < 4 || READ_BE_UINT32(data) != MKID_BE('CMP '))
|
||||||
error("Invalid magic loading colormap");
|
error("Invalid magic loading colormap");
|
||||||
memcpy(_colors, data + 64, sizeof(_colors));
|
memcpy(_colors, data + 64, sizeof(_colors));
|
||||||
}
|
}
|
||||||
|
CMap() : Object() {}
|
||||||
|
~CMap() {
|
||||||
|
if (g_resourceloader)
|
||||||
|
g_resourceloader->uncacheColormap(this);
|
||||||
|
}
|
||||||
const char *filename() const { return _fname.c_str(); }
|
const char *filename() const { return _fname.c_str(); }
|
||||||
|
|
||||||
// The color data, in RGB format
|
// The color data, in RGB format
|
||||||
char _colors[256 * 3];
|
char _colors[256 * 3];
|
||||||
Common::String _fname;
|
Common::String _fname;
|
||||||
|
|
||||||
|
bool operator==(const CMap &c) const {
|
||||||
|
if (_fname != c._fname) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -124,11 +124,12 @@ public:
|
||||||
~ModelComponent();
|
~ModelComponent();
|
||||||
|
|
||||||
Model::HierNode *hierarchy() { return _hier; }
|
Model::HierNode *hierarchy() { return _hier; }
|
||||||
|
int numNodes() { return _obj->numNodes(); }
|
||||||
void draw();
|
void draw();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Common::String _filename;
|
Common::String _filename;
|
||||||
Model *_obj;
|
ModelPtr _obj;
|
||||||
Model::HierNode *_hier;
|
Model::HierNode *_hier;
|
||||||
Graphics::Matrix4 _matrix;
|
Graphics::Matrix4 _matrix;
|
||||||
};
|
};
|
||||||
|
@ -241,10 +242,11 @@ void ModelComponent::init() {
|
||||||
if (gDebugLevel == DEBUG_MODEL || gDebugLevel == DEBUG_WARN || gDebugLevel == DEBUG_ALL)
|
if (gDebugLevel == DEBUG_MODEL || gDebugLevel == DEBUG_WARN || gDebugLevel == DEBUG_ALL)
|
||||||
warning("No colormap specified for %s, using %s", _filename.c_str(), DEFAULT_COLORMAP);
|
warning("No colormap specified for %s, using %s", _filename.c_str(), DEFAULT_COLORMAP);
|
||||||
|
|
||||||
cm = g_resourceloader->loadColormap(DEFAULT_COLORMAP);
|
cm = g_resourceloader->getColormap(DEFAULT_COLORMAP);
|
||||||
}
|
}
|
||||||
_obj = g_resourceloader->loadModel(_filename.c_str(), cm);
|
_obj = g_resourceloader->getModel(_filename.c_str(), cm);
|
||||||
_hier = _obj->copyHierarchy();
|
_hier = _obj->copyHierarchy();
|
||||||
|
|
||||||
// Use parent availablity to decide whether to default the
|
// Use parent availablity to decide whether to default the
|
||||||
// component to being visible
|
// component to being visible
|
||||||
if (!_parent || !_parent->visible())
|
if (!_parent || !_parent->visible())
|
||||||
|
@ -297,8 +299,9 @@ void ModelComponent::resetColormap() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelComponent::~ModelComponent() {
|
ModelComponent::~ModelComponent() {
|
||||||
if (_hier && _hier->_parent)
|
if (_hier && _hier->_parent) {
|
||||||
_hier->_parent->removeChild(_hier);
|
_hier->_parent->removeChild(_hier);
|
||||||
|
}
|
||||||
|
|
||||||
delete[] _hier;
|
delete[] _hier;
|
||||||
}
|
}
|
||||||
|
@ -316,13 +319,16 @@ void translateObject(Model::HierNode *node, bool reset) {
|
||||||
void ModelComponent::draw() {
|
void ModelComponent::draw() {
|
||||||
// If the object was drawn by being a component
|
// If the object was drawn by being a component
|
||||||
// of it's parent then don't draw it
|
// of it's parent then don't draw it
|
||||||
|
|
||||||
if (_parent && _parent->visible())
|
if (_parent && _parent->visible())
|
||||||
return;
|
return;
|
||||||
// Need to translate object to be in accordance
|
// Need to translate object to be in accordance
|
||||||
// with the setup of the parent
|
// with the setup of the parent
|
||||||
if (_hier->_parent)
|
if (_hier->_parent)
|
||||||
translateObject(_hier->_parent, false);
|
translateObject(_hier->_parent, false);
|
||||||
|
|
||||||
_hier->draw();
|
_hier->draw();
|
||||||
|
|
||||||
// Need to un-translate when done
|
// Need to un-translate when done
|
||||||
if (_hier->_parent)
|
if (_hier->_parent)
|
||||||
translateObject(_hier->_parent, true);
|
translateObject(_hier->_parent, true);
|
||||||
|
@ -376,14 +382,14 @@ public:
|
||||||
~MaterialComponent() { }
|
~MaterialComponent() { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Material *_mat;
|
MaterialPtr _mat;
|
||||||
Common::String _filename;
|
Common::String _filename;
|
||||||
int _num;
|
int _num;
|
||||||
};
|
};
|
||||||
|
|
||||||
ColormapComponent::ColormapComponent(Costume::Component *p, int parentID, const char *filename, tag32 t) :
|
ColormapComponent::ColormapComponent(Costume::Component *p, int parentID, const char *filename, tag32 t) :
|
||||||
Costume::Component(p, parentID, t) {
|
Costume::Component(p, parentID, t) {
|
||||||
_cmap = g_resourceloader->loadColormap(filename);
|
_cmap = g_resourceloader->getColormap(filename);
|
||||||
|
|
||||||
if (p)
|
if (p)
|
||||||
p->setColormap(_cmap);
|
p->setColormap(_cmap);
|
||||||
|
@ -404,7 +410,7 @@ public:
|
||||||
~KeyframeComponent() {}
|
~KeyframeComponent() {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KeyframeAnim *_keyf;
|
KeyframeAnimPtr _keyf;
|
||||||
int _priority1, _priority2;
|
int _priority1, _priority2;
|
||||||
Model::HierNode *_hier;
|
Model::HierNode *_hier;
|
||||||
bool _active;
|
bool _active;
|
||||||
|
@ -419,10 +425,10 @@ KeyframeComponent::KeyframeComponent(Costume::Component *p, int parentID, const
|
||||||
const char *comma = strchr(filename, ',');
|
const char *comma = strchr(filename, ',');
|
||||||
if (comma) {
|
if (comma) {
|
||||||
Common::String realName(filename, comma);
|
Common::String realName(filename, comma);
|
||||||
_keyf = g_resourceloader->loadKeyframe(realName.c_str());
|
_keyf = g_resourceloader->getKeyframe(realName.c_str());
|
||||||
sscanf(comma + 1, "%d,%d", &_priority1, &_priority2);
|
sscanf(comma + 1, "%d,%d", &_priority1, &_priority2);
|
||||||
} else
|
} else
|
||||||
_keyf = g_resourceloader->loadKeyframe(filename);
|
_keyf = g_resourceloader->getKeyframe(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyframeComponent::setKey(int val) {
|
void KeyframeComponent::setKey(int val) {
|
||||||
|
@ -541,9 +547,9 @@ void MaterialComponent::init() {
|
||||||
if (gDebugLevel == DEBUG_MODEL || gDebugLevel == DEBUG_WARN || gDebugLevel == DEBUG_ALL)
|
if (gDebugLevel == DEBUG_MODEL || gDebugLevel == DEBUG_WARN || gDebugLevel == DEBUG_ALL)
|
||||||
warning("MaterialComponent::init on %s", _filename.c_str());
|
warning("MaterialComponent::init on %s", _filename.c_str());
|
||||||
|
|
||||||
cm = g_resourceloader->loadColormap(DEFAULT_COLORMAP);
|
cm = g_resourceloader->getColormap(DEFAULT_COLORMAP);
|
||||||
}
|
}
|
||||||
_mat = g_resourceloader->loadMaterial(_filename.c_str(), cm);
|
_mat = g_resourceloader->getMaterial(_filename.c_str(), cm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialComponent::setKey(int val) {
|
void MaterialComponent::setKey(int val) {
|
||||||
|
@ -583,9 +589,9 @@ public:
|
||||||
void setKey(int val);
|
void setKey(int val);
|
||||||
void reset();
|
void reset();
|
||||||
~SoundComponent() {
|
~SoundComponent() {
|
||||||
// Stop the sound if it's in progress
|
// Stop the sound if it's in progress
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Common::String _soundName;
|
Common::String _soundName;
|
||||||
|
@ -626,12 +632,27 @@ void SoundComponent::setKey(int val) {
|
||||||
|
|
||||||
void SoundComponent::reset() {
|
void SoundComponent::reset() {
|
||||||
// A lot of the sound components this gets called against aren't actually running
|
// A lot of the sound components this gets called against aren't actually running
|
||||||
if (g_imuse->getSoundStatus(_soundName.c_str()))
|
if (g_imuse && g_imuse->getSoundStatus(_soundName.c_str()))
|
||||||
g_imuse->stopSound(_soundName.c_str());
|
g_imuse->stopSound(_soundName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
Costume::Costume(const char *fname, const char *data, int len, Costume *prevCost) :
|
Costume::Costume(const char *fname, const char *data, int len, Costume *prevCost) :
|
||||||
_fname(fname), _cmap(NULL) {
|
Object() {
|
||||||
|
|
||||||
|
load(fname, data, len, prevCost);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Costume::load(const char *filename, const char *data, int len, Costume *prevCost) {
|
||||||
|
_fname = filename;
|
||||||
|
_headNode = NULL;
|
||||||
|
_neckNode = NULL;
|
||||||
|
_head.maxPitch = 0;
|
||||||
|
_headYaw = 0;
|
||||||
|
_headPitch = 0;
|
||||||
|
_lastTime = 0;
|
||||||
|
_headZ = 0;
|
||||||
|
_prevCostume = prevCost;
|
||||||
|
|
||||||
TextSplitter ts(data, len);
|
TextSplitter ts(data, len);
|
||||||
|
|
||||||
ts.expectString("costume v0.1");
|
ts.expectString("costume v0.1");
|
||||||
|
@ -714,20 +735,55 @@ Costume::Costume(const char *fname, const char *data, int len, Costume *prevCost
|
||||||
ts.scanString("chore %d", 1, &which);
|
ts.scanString("chore %d", 1, &which);
|
||||||
_chores[which].load(this, ts);
|
_chores[which].load(this, ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Model::HierNode *hier = 0;
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < _numComponents; i++) {
|
||||||
|
if (!_components[i])
|
||||||
|
continue;
|
||||||
|
// Needs to handle Main Models (pigeons) and normal Models
|
||||||
|
// (when Manny climbs the rope)
|
||||||
|
if (FROM_BE_32(_components[i]->tag()) == MKID_BE('MMDL')) {
|
||||||
|
ModelComponent *c = static_cast<ModelComponent *>(_components[i]);
|
||||||
|
hier = c->hierarchy();
|
||||||
|
count = c->numNodes();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (strcmp(hier[i]._name, "m_head_2") == 0) {
|
||||||
|
_headNode = hier + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_headNode) {
|
||||||
|
Model::HierNode *hn = _headNode->_parent;
|
||||||
|
while (hn) {
|
||||||
|
_headZ += hn->_animPos.z();
|
||||||
|
if (strcmp(hn->_name, "m_nck_b1") == 0)
|
||||||
|
_neckNode = hn;
|
||||||
|
hn = hn->_parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Costume::~Costume() {
|
Costume::~Costume() {
|
||||||
stopChores();
|
if (_chores) {
|
||||||
for (int i = _numComponents - 1; i >= 0; i--) {
|
stopChores();
|
||||||
// The "Sprite" component can be NULL
|
for (int i = _numComponents - 1; i >= 0; i--) {
|
||||||
if (_components[i])
|
// The "Sprite" component can be NULL
|
||||||
delete _components[i];
|
if (_components[i])
|
||||||
|
delete _components[i];
|
||||||
|
}
|
||||||
|
delete[] _components;
|
||||||
|
delete[] _chores;
|
||||||
|
g_resourceloader->uncacheCostume(this);
|
||||||
}
|
}
|
||||||
delete[] _components;
|
|
||||||
delete[] _chores;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Costume::Component::Component(Component *p, int parentID, tag32 t) {
|
Costume::Component::Component(Component *p, int parentID, tag32 t) {
|
||||||
_visible = true;
|
_visible = true;
|
||||||
_previousCmap = NULL;
|
_previousCmap = NULL;
|
||||||
_cmap = NULL;
|
_cmap = NULL;
|
||||||
|
@ -952,7 +1008,7 @@ void Costume::setColormap(const char *map) {
|
||||||
// see where raoul is gone in hh.set
|
// see where raoul is gone in hh.set
|
||||||
if (!map)
|
if (!map)
|
||||||
return;
|
return;
|
||||||
_cmap = g_resourceloader->loadColormap(map);
|
_cmap = g_resourceloader->getColormap(map);
|
||||||
for (int i = 0; i < _numComponents; i++)
|
for (int i = 0; i < _numComponents; i++)
|
||||||
_components[i]->setColormap(NULL);
|
_components[i]->setColormap(NULL);
|
||||||
}
|
}
|
||||||
|
@ -1007,6 +1063,120 @@ void Costume::update() {
|
||||||
_components[i]->update();
|
_components[i]->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moveHead();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Costume::moveHead() {
|
||||||
|
if (_headNode && _head.maxPitch) {
|
||||||
|
Model::HierNode *p = _headNode->_parent;
|
||||||
|
if (p && strcmp(p->_name, "m_head_2") == 0) { //Strange enough, when talking happens that a
|
||||||
|
//new "m_head_2" gets created as the parent of
|
||||||
|
//the old one.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int time = g_system->getMillis();
|
||||||
|
const int elapsed = time - _lastTime;
|
||||||
|
_lastTime = time;
|
||||||
|
float yawStep = 0.3 * elapsed;
|
||||||
|
float pitchStep = 0.1 * elapsed;
|
||||||
|
if (_lookAt.isZero()) {
|
||||||
|
//animate yaw
|
||||||
|
if (_headYaw > yawStep) {
|
||||||
|
_headYaw -= yawStep;
|
||||||
|
} else if (_headYaw < -yawStep) {
|
||||||
|
_headYaw += yawStep;
|
||||||
|
} else {
|
||||||
|
_headYaw = 0;
|
||||||
|
}
|
||||||
|
//animate pitch
|
||||||
|
if (_headPitch > pitchStep) {
|
||||||
|
_headPitch -= pitchStep;
|
||||||
|
} else if (_headPitch < -pitchStep) {
|
||||||
|
_headPitch += pitchStep;
|
||||||
|
} else {
|
||||||
|
_headPitch = 0;
|
||||||
|
}
|
||||||
|
_headNode->_animYaw = _headYaw;
|
||||||
|
_neckNode->_animPitch = _headPitch;
|
||||||
|
_headNode->_animRoll = _headNode->_animYaw / 10.;
|
||||||
|
|
||||||
|
if (_headNode->_animRoll > _head.maxRoll)
|
||||||
|
_headNode->_animRoll = _head.maxRoll;
|
||||||
|
if (_headNode->_animRoll < -_head.maxRoll)
|
||||||
|
_headNode->_animRoll = -_head.maxRoll;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics::Vector3d v = -(_headNode->_animPos + _matrix._pos + Graphics::Vector3d(0, 0, _headZ)) + _lookAt;
|
||||||
|
if (v.isZero()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// cout<<_lookAt.x()<<" "<<_lookAt.y()<<" "<<_lookAt.z()<<" "<<v.x()<<" "<<v.y()<<" "<<v.z()<<endl;
|
||||||
|
float magnitude = sqrt(v.x() * v.x() + v.y() * v.y());
|
||||||
|
float a = v.x() / magnitude;
|
||||||
|
float b = v.y() / magnitude;
|
||||||
|
float yaw;
|
||||||
|
yaw = acos(a) * (180.0f / LOCAL_PI);
|
||||||
|
if (b < 0.0f)
|
||||||
|
yaw = 360.0f - yaw;
|
||||||
|
|
||||||
|
float h = sqrt(v.x() * v.x() + v.y() * v.y());
|
||||||
|
magnitude = sqrt(v.z() * v.z() + h * h);
|
||||||
|
a = h / magnitude;
|
||||||
|
b = v.z() / magnitude;
|
||||||
|
float pitch;
|
||||||
|
pitch = acos(a) * (180.0f / LOCAL_PI);
|
||||||
|
if (b < 0.0f)
|
||||||
|
pitch = 360.0f - pitch;
|
||||||
|
|
||||||
|
_neckNode->_animPitch = pitch;
|
||||||
|
_headNode->_animYaw = - 90 + yaw - _matrix._rot.getYaw();
|
||||||
|
|
||||||
|
if (_neckNode->_animPitch > 180)
|
||||||
|
_neckNode->_animPitch -= 360;
|
||||||
|
|
||||||
|
if (_headNode->_animYaw < 0)
|
||||||
|
_headNode->_animYaw += 360.;
|
||||||
|
if (_headNode->_animYaw > 180.)
|
||||||
|
_headNode->_animYaw -= 360;
|
||||||
|
|
||||||
|
//animate pitch
|
||||||
|
if (_neckNode->_animPitch - _headPitch > pitchStep)
|
||||||
|
_neckNode->_animPitch = _headPitch + pitchStep;
|
||||||
|
if (_headPitch - _neckNode->_animPitch > pitchStep)
|
||||||
|
_neckNode->_animPitch = _headPitch - pitchStep;
|
||||||
|
//animate yaw
|
||||||
|
if (_headNode->_animYaw - _headYaw > yawStep)
|
||||||
|
_headNode->_animYaw = _headYaw + yawStep;
|
||||||
|
if (_headYaw - _headNode->_animYaw > yawStep)
|
||||||
|
_headNode->_animYaw = _headYaw - yawStep;
|
||||||
|
|
||||||
|
if (_neckNode->_animPitch > _head.maxPitch)
|
||||||
|
_neckNode->_animPitch = _head.maxPitch;
|
||||||
|
if (_neckNode->_animPitch < -_head.maxPitch)
|
||||||
|
_neckNode->_animPitch = -_head.maxPitch;
|
||||||
|
|
||||||
|
if (_headNode->_animYaw > _head.maxYaw)
|
||||||
|
_headNode->_animYaw = _head.maxYaw;
|
||||||
|
if (_headNode->_animYaw < -_head.maxYaw)
|
||||||
|
_headNode->_animYaw = -_head.maxYaw;
|
||||||
|
|
||||||
|
_headNode->_animRoll = _headNode->_animYaw / 10.;
|
||||||
|
|
||||||
|
if (_headNode->_animRoll > _head.maxRoll)
|
||||||
|
_headNode->_animRoll = _head.maxRoll;
|
||||||
|
if (_headNode->_animRoll < -_head.maxRoll)
|
||||||
|
_headNode->_animRoll = -_head.maxRoll;
|
||||||
|
|
||||||
|
_headPitch = _neckNode->_animPitch;
|
||||||
|
_headYaw = _headNode->_animYaw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Costume::setLookAt(const Graphics::Vector3d &vec) {
|
||||||
|
_lookAt = vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Costume::setHead(int joint1, int joint2, int joint3, float maxRoll, float maxPitch, float maxYaw) {
|
void Costume::setHead(int joint1, int joint2, int joint3, float maxRoll, float maxPitch, float maxYaw) {
|
||||||
|
@ -1023,4 +1193,62 @@ void Costume::setPosRotate(Graphics::Vector3d pos, float pitch, float yaw, float
|
||||||
_matrix._rot.buildFromPitchYawRoll(pitch, yaw, roll);
|
_matrix._rot.buildFromPitchYawRoll(pitch, yaw, roll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Costume *Costume::previousCostume() const {
|
||||||
|
return _prevCostume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Costume::saveState(SaveGame *state) const {
|
||||||
|
if (_cmap) {
|
||||||
|
state->writeLEUint32(1);
|
||||||
|
state->writeCharString(_cmap->filename());
|
||||||
|
} else {
|
||||||
|
state->writeLEUint32(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _numChores; ++i) {
|
||||||
|
Chore &c = _chores[i];
|
||||||
|
|
||||||
|
state->writeLESint32(c._hasPlayed);
|
||||||
|
state->writeLESint32(c._playing);
|
||||||
|
state->writeLESint32(c._looping);
|
||||||
|
state->writeLESint32(c._currTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _numComponents; ++i) {
|
||||||
|
Component *c = _components[i];
|
||||||
|
|
||||||
|
if (c) {
|
||||||
|
state->writeLESint32(c->_visible);
|
||||||
|
state->writeVector3d(c->_matrix._pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Costume::restoreState(SaveGame *state) {
|
||||||
|
if (state->readLEUint32()) {
|
||||||
|
const char *str = state->readCharString();
|
||||||
|
setColormap(str);
|
||||||
|
delete[] str;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _numChores; ++i) {
|
||||||
|
Chore &c = _chores[i];
|
||||||
|
|
||||||
|
c._hasPlayed = state->readLESint32();
|
||||||
|
c._playing = state->readLESint32();
|
||||||
|
c._looping = state->readLESint32();
|
||||||
|
c._currTime = state->readLESint32();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < _numComponents; ++i) {
|
||||||
|
Component *c = _components[i];
|
||||||
|
|
||||||
|
if (c) {
|
||||||
|
c->_visible = state->readLESint32();
|
||||||
|
c->_matrix._pos = state->readVector3d();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#define GRIM_COSTUME_H
|
#define GRIM_COSTUME_H
|
||||||
|
|
||||||
#include "engines/grim/model.h"
|
#include "engines/grim/model.h"
|
||||||
|
#include "engines/grim/object.h"
|
||||||
|
#include "engines/grim/colormap.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
@ -34,11 +36,15 @@ namespace Grim {
|
||||||
|
|
||||||
typedef uint32 tag32;
|
typedef uint32 tag32;
|
||||||
|
|
||||||
class Costume {
|
class Costume : public Object {
|
||||||
|
GRIM_OBJECT(Costume)
|
||||||
public:
|
public:
|
||||||
Costume(const char *filename, const char *data, int len, Costume *prevCost);
|
Costume(const char *filename, const char *data, int len, Costume *prevCost);
|
||||||
|
Costume() : Object() { _chores = 0; }
|
||||||
|
|
||||||
~Costume();
|
void load(const char *filename, const char *data, int len, Costume *prevCost);
|
||||||
|
|
||||||
|
virtual ~Costume();
|
||||||
|
|
||||||
const char *filename() const { return _fname.c_str(); }
|
const char *filename() const { return _fname.c_str(); }
|
||||||
void playChore(int num);
|
void playChore(int num);
|
||||||
|
@ -47,12 +53,14 @@ public:
|
||||||
void setChoreLooping(int num, bool val) { _chores[num].setLooping(val); }
|
void setChoreLooping(int num, bool val) { _chores[num].setLooping(val); }
|
||||||
void stopChore(int num) { _chores[num].stop(); }
|
void stopChore(int num) { _chores[num].stop(); }
|
||||||
Model::HierNode *getModelNodes();
|
Model::HierNode *getModelNodes();
|
||||||
|
Model *getModel();
|
||||||
void setColormap(const char *map);
|
void setColormap(const char *map);
|
||||||
void stopChores();
|
void stopChores();
|
||||||
int isChoring(const char *name, bool excludeLooping);
|
int isChoring(const char *name, bool excludeLooping);
|
||||||
int isChoring(int num, bool excludeLooping);
|
int isChoring(int num, bool excludeLooping);
|
||||||
int isChoring(bool excludeLooping);
|
int isChoring(bool excludeLooping);
|
||||||
|
|
||||||
|
void setLookAt(const Graphics::Vector3d &vec);
|
||||||
void setHead(int joint1, int joint2, int joint3, float maxRoll, float maxPitch, float maxYaw);
|
void setHead(int joint1, int joint2, int joint3, float maxRoll, float maxPitch, float maxYaw);
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
@ -60,6 +68,11 @@ public:
|
||||||
void draw();
|
void draw();
|
||||||
void setPosRotate(Graphics::Vector3d pos, float pitch, float yaw, float roll);
|
void setPosRotate(Graphics::Vector3d pos, float pitch, float yaw, float roll);
|
||||||
|
|
||||||
|
Costume *previousCostume() const;
|
||||||
|
|
||||||
|
void saveState(SaveGame *state) const;
|
||||||
|
bool restoreState(SaveGame *state);
|
||||||
|
|
||||||
class Component {
|
class Component {
|
||||||
public:
|
public:
|
||||||
Component(Component *parent, int parentID, tag32 tag);
|
Component(Component *parent, int parentID, tag32 tag);
|
||||||
|
@ -80,7 +93,7 @@ public:
|
||||||
virtual ~Component() { }
|
virtual ~Component() { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CMap *_cmap, *_previousCmap;
|
CMapPtr _cmap, _previousCmap;
|
||||||
tag32 _tag;
|
tag32 _tag;
|
||||||
int _parentID;
|
int _parentID;
|
||||||
bool _visible;
|
bool _visible;
|
||||||
|
@ -95,7 +108,10 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Component *loadComponent(tag32 tag, Component *parent, int parentID, const char *name, Component *prevComponent);
|
Component *loadComponent(tag32 tag, Component *parent, int parentID, const char *name, Component *prevComponent);
|
||||||
Common::String _fname;
|
void moveHead();
|
||||||
|
|
||||||
|
Common::String _fname;
|
||||||
|
CostumePtr _prevCostume;
|
||||||
|
|
||||||
int _numComponents;
|
int _numComponents;
|
||||||
Component **_components;
|
Component **_components;
|
||||||
|
@ -147,10 +163,18 @@ private:
|
||||||
friend class Costume;
|
friend class Costume;
|
||||||
};
|
};
|
||||||
|
|
||||||
CMap *_cmap;
|
CMapPtr _cmap;
|
||||||
int _numChores;
|
int _numChores;
|
||||||
Chore *_chores;
|
Chore *_chores;
|
||||||
Graphics::Matrix4 _matrix;
|
Graphics::Matrix4 _matrix;
|
||||||
|
Model::HierNode *_headNode;
|
||||||
|
Model::HierNode *_neckNode;
|
||||||
|
float _headZ;
|
||||||
|
Graphics::Vector3d _lookAt;
|
||||||
|
|
||||||
|
float _headPitch;
|
||||||
|
float _headYaw;
|
||||||
|
int _lastTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -26,58 +26,190 @@
|
||||||
#include "common/endian.h"
|
#include "common/endian.h"
|
||||||
|
|
||||||
#include "engines/grim/grim.h"
|
#include "engines/grim/grim.h"
|
||||||
|
#include "engines/grim/savegame.h"
|
||||||
#include "engines/grim/font.h"
|
#include "engines/grim/font.h"
|
||||||
|
#include "engines/grim/lua.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
Font::Font(const char *filename, const char *data, int /*len*/) {
|
Font::Font(const char *filename, const char *data, int len) : Object() {
|
||||||
_fname = filename;
|
load(filename, data, len);
|
||||||
|
|
||||||
_filename = filename;
|
|
||||||
_numChars = READ_LE_UINT32(data);
|
|
||||||
_dataSize = READ_LE_UINT32(data + 4);
|
|
||||||
_height = READ_LE_UINT32(data + 8);
|
|
||||||
_baseOffsetY = READ_LE_UINT32(data + 12);
|
|
||||||
_firstChar = READ_LE_UINT32(data + 24);
|
|
||||||
_lastChar = READ_LE_UINT32(data + 28);
|
|
||||||
|
|
||||||
data += 32;
|
|
||||||
|
|
||||||
// Read character indexes - are the key/value reversed?
|
|
||||||
_charIndex = new uint16[_numChars];
|
|
||||||
if (!_charIndex)
|
|
||||||
error("Could not load font %s. Out of memory", filename);
|
|
||||||
for (uint i = 0; i < _numChars; ++i) {
|
|
||||||
_charIndex[i] = READ_LE_UINT16(data + 2 * i);
|
|
||||||
}
|
|
||||||
|
|
||||||
data += _numChars * 2;
|
|
||||||
|
|
||||||
// Read character headers
|
|
||||||
_charHeaders = new CharHeader[_numChars];
|
|
||||||
if (!_charHeaders)
|
|
||||||
error("Could not load font %s. Out of memory", filename);
|
|
||||||
for (uint i = 0; i < _numChars; ++i) {
|
|
||||||
_charHeaders[i].offset = READ_LE_UINT32(data);
|
|
||||||
_charHeaders[i].width = *(int8 *)(data + 4);
|
|
||||||
_charHeaders[i].startingCol = *(int8 *)(data + 5);
|
|
||||||
_charHeaders[i].startingLine = *(int8 *)(data + 6);
|
|
||||||
_charHeaders[i].dataWidth = READ_LE_UINT32(data + 8);
|
|
||||||
_charHeaders[i].dataHeight = READ_LE_UINT32(data + 12);
|
|
||||||
data += 16;
|
|
||||||
}
|
|
||||||
// Read font data
|
|
||||||
_fontData = new byte[_dataSize];
|
|
||||||
if (!_fontData)
|
|
||||||
error("Could not load font %s. Out of memory", filename);
|
|
||||||
|
|
||||||
memcpy(_fontData, data, _dataSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Font::~Font() {
|
Font::~Font() {
|
||||||
delete[] _charIndex;
|
if (_charIndex) {
|
||||||
delete[] _charHeaders;
|
delete[] _charIndex;
|
||||||
delete[] _fontData;
|
delete[] _charHeaders;
|
||||||
|
delete[] _fontData;
|
||||||
|
|
||||||
|
g_resourceloader->uncacheFont(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Font::load(const char *filename, const char *data, int len) {
|
||||||
|
_fname = filename;
|
||||||
|
|
||||||
|
_filename = filename;
|
||||||
|
_numChars = READ_LE_UINT32(data);
|
||||||
|
_dataSize = READ_LE_UINT32(data + 4);
|
||||||
|
_height = READ_LE_UINT32(data + 8);
|
||||||
|
_baseOffsetY = READ_LE_UINT32(data + 12);
|
||||||
|
_firstChar = READ_LE_UINT32(data + 24);
|
||||||
|
_lastChar = READ_LE_UINT32(data + 28);
|
||||||
|
|
||||||
|
data += 32;
|
||||||
|
|
||||||
|
// Read character indexes - are the key/value reversed?
|
||||||
|
_charIndex = new uint16[_numChars];
|
||||||
|
if (!_charIndex)
|
||||||
|
error("Could not load font %s. Out of memory", filename);
|
||||||
|
for (uint i = 0; i < _numChars; ++i) {
|
||||||
|
_charIndex[i] = READ_LE_UINT16(data + 2 * i);
|
||||||
|
}
|
||||||
|
|
||||||
|
data += _numChars * 2;
|
||||||
|
|
||||||
|
// Read character headers
|
||||||
|
_charHeaders = new CharHeader[_numChars];
|
||||||
|
if (!_charHeaders)
|
||||||
|
error("Could not load font %s. Out of memory", filename);
|
||||||
|
for (uint i = 0; i < _numChars; ++i) {
|
||||||
|
_charHeaders[i].offset = READ_LE_UINT32(data);
|
||||||
|
_charHeaders[i].width = *(int8 *)(data + 4);
|
||||||
|
_charHeaders[i].startingCol = *(int8 *)(data + 5);
|
||||||
|
_charHeaders[i].startingLine = *(int8 *)(data + 6);
|
||||||
|
_charHeaders[i].dataWidth = READ_LE_UINT32(data + 8);
|
||||||
|
_charHeaders[i].dataHeight = READ_LE_UINT32(data + 12);
|
||||||
|
data += 16;
|
||||||
|
}
|
||||||
|
// Read font data
|
||||||
|
_fontData = new byte[_dataSize];
|
||||||
|
if (!_fontData)
|
||||||
|
error("Could not load font %s. Out of memory", filename);
|
||||||
|
|
||||||
|
memcpy(_fontData, data, _dataSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Font::saveState(SaveGame *savedState) const {
|
||||||
|
int32 size;
|
||||||
|
const char *str;
|
||||||
|
|
||||||
|
str = _fname.c_str();
|
||||||
|
size = strlen(str);
|
||||||
|
savedState->writeLESint32(size);
|
||||||
|
savedState->write(str, size);
|
||||||
|
|
||||||
|
// savedState->writeLESint32(_fname.size());
|
||||||
|
// savedState->write(_fname.c_str(), _fname.size());
|
||||||
|
// savedState->writeLESint32(_filename.size());
|
||||||
|
// savedState->write(_filename.c_str(), _filename.size());
|
||||||
|
//
|
||||||
|
// //_fontData
|
||||||
|
// savedState->writeLEUint32(_dataSize);
|
||||||
|
// PointerId ptr = makeIdFromPointer(_fontData);
|
||||||
|
// // cout<<ptr.low<<endl;
|
||||||
|
// savedState->writeLEUint32(ptr.low);
|
||||||
|
// savedState->writeLEUint32(ptr.hi);
|
||||||
|
// for (uint32 i = 0; i < _dataSize; ++i) {
|
||||||
|
// savedState->writeByte(_fontData[i]);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //_charHeaders
|
||||||
|
// savedState->writeLEUint32(_numChars);
|
||||||
|
// ptr = makeIdFromPointer(_charHeaders);
|
||||||
|
// savedState->writeLEUint32(ptr.low);
|
||||||
|
// savedState->writeLEUint32(ptr.hi);
|
||||||
|
// // cout<<_numChars<<endl;
|
||||||
|
// for (uint32 i = 0; i < _numChars; ++i) {
|
||||||
|
// savedState->writeLESint32(_charHeaders[i].offset);
|
||||||
|
// savedState->writeLESint32(_charHeaders[i].width);
|
||||||
|
// savedState->writeLESint32(_charHeaders[i].startingCol);
|
||||||
|
// savedState->writeLESint32(_charHeaders[i].startingLine);
|
||||||
|
// savedState->writeLESint32(_charHeaders[i].dataWidth);
|
||||||
|
// savedState->writeLESint32(_charHeaders[i].dataHeight);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //_charIndex
|
||||||
|
// ptr = makeIdFromPointer(_charIndex);
|
||||||
|
// savedState->writeLEUint32(ptr.low);
|
||||||
|
// savedState->writeLEUint32(ptr.hi);
|
||||||
|
// for (uint32 i = 0; i < _numChars; ++i) {
|
||||||
|
// savedState->writeLEUint32(_charIndex[i]);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// savedState->writeLEUint32(_firstChar);
|
||||||
|
// savedState->writeLEUint32(_lastChar);
|
||||||
|
// savedState->writeLEUint32(_height);
|
||||||
|
// savedState->writeLEUint32(_baseOffsetY);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Font::restoreState(SaveGame *savedState) {
|
||||||
|
int32 size;
|
||||||
|
char *str = 0;
|
||||||
|
|
||||||
|
// load actor name
|
||||||
|
size = savedState->readLESint32();
|
||||||
|
str = new char[size + 1];
|
||||||
|
savedState->read(str, size);
|
||||||
|
str[size] = '\0';
|
||||||
|
|
||||||
|
Block *b = g_resourceloader->getBlock(str);
|
||||||
|
if (b) {
|
||||||
|
load(str, b->data(), b->len());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
delete[] str;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// int32 size = savedState->readLESint32();
|
||||||
|
// char *str = new char[size];
|
||||||
|
// savedState->read(str, size);
|
||||||
|
// _fname.load(str, size);
|
||||||
|
// delete str;
|
||||||
|
// size = savedState->readLESint32();
|
||||||
|
// str = new char[size];
|
||||||
|
// savedState->read(str, size);
|
||||||
|
// _filename.load(str, size);
|
||||||
|
// delete str;
|
||||||
|
//
|
||||||
|
// _dataSize = savedState->readLEUint32();
|
||||||
|
// PointerId ptr;
|
||||||
|
// ptr.low = savedState->readLEUint32();
|
||||||
|
// ptr.hi = savedState->readLEUint32();
|
||||||
|
// _fontData = static_cast<byte *>(makePointerFromId(ptr));
|
||||||
|
// for (uint32 i = 0; i < _dataSize; ++i) {
|
||||||
|
// _fontData[i] = savedState->readByte();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// _numChars = savedState->readLEUint32();
|
||||||
|
// ptr.low = savedState->readLEUint32();
|
||||||
|
// ptr.hi = savedState->readLEUint32();
|
||||||
|
// _charHeaders = static_cast<CharHeader *>(makePointerFromId(ptr));
|
||||||
|
// for (uint32 i = 0; i < _numChars; ++i) {
|
||||||
|
// _charHeaders[i].offset = savedState->readLESint32();
|
||||||
|
// _charHeaders[i].width = savedState->readLESint32();
|
||||||
|
// _charHeaders[i].startingCol = savedState->readLESint32();
|
||||||
|
// _charHeaders[i].startingLine = savedState->readLESint32();
|
||||||
|
// _charHeaders[i].dataWidth = savedState->readLESint32();
|
||||||
|
// _charHeaders[i].dataHeight = savedState->readLESint32();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //_charIndex
|
||||||
|
// ptr.low = savedState->readLEUint32();
|
||||||
|
// ptr.hi = savedState->readLEUint32();
|
||||||
|
// _charIndex = static_cast<uint16 *>(makePointerFromId(ptr));
|
||||||
|
// for (uint32 i = 0; i < _numChars; ++i) {
|
||||||
|
// _charIndex[i] = savedState->readLEUint32();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// _firstChar = savedState->readLEUint32();
|
||||||
|
// _lastChar = savedState->readLEUint32();
|
||||||
|
// _height = savedState->readLEUint32();
|
||||||
|
// _baseOffsetY = savedState->readLEUint32();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 Font::getCharIndex(unsigned char c) {
|
uint16 Font::getCharIndex(unsigned char c) {
|
||||||
|
|
|
@ -27,14 +27,21 @@
|
||||||
#define GRIM_FONT_H
|
#define GRIM_FONT_H
|
||||||
|
|
||||||
#include "engines/grim/resource.h"
|
#include "engines/grim/resource.h"
|
||||||
|
#include "engines/grim/object.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
class Font {
|
class SaveGame;
|
||||||
|
|
||||||
|
class Font : public Object {
|
||||||
|
GRIM_OBJECT(Font)
|
||||||
public:
|
public:
|
||||||
Font(const char *filename, const char *data, int len);
|
Font(const char *filename, const char *data, int len);
|
||||||
|
Font() : Object() { _charIndex = 0; }
|
||||||
~Font();
|
~Font();
|
||||||
|
|
||||||
|
void load(const char *filename, const char *data, int len);
|
||||||
|
|
||||||
Common::String getFilename() { return _filename; }
|
Common::String getFilename() { return _filename; }
|
||||||
int32 getHeight() { return _height; }
|
int32 getHeight() { return _height; }
|
||||||
int32 getBaseOffsetY() { return _baseOffsetY; }
|
int32 getBaseOffsetY() { return _baseOffsetY; }
|
||||||
|
@ -45,6 +52,9 @@ public:
|
||||||
int32 getCharStartingLine(unsigned char c) { return _charHeaders[getCharIndex(c)].startingLine; }
|
int32 getCharStartingLine(unsigned char c) { return _charHeaders[getCharIndex(c)].startingLine; }
|
||||||
const byte *getCharData(unsigned char c) { return _fontData + (_charHeaders[getCharIndex(c)].offset); }
|
const byte *getCharData(unsigned char c) { return _fontData + (_charHeaders[getCharIndex(c)].offset); }
|
||||||
|
|
||||||
|
void saveState(SaveGame *savedState) const;
|
||||||
|
bool restoreState(SaveGame *savedState);
|
||||||
|
|
||||||
static const uint8 emerFont[][13];
|
static const uint8 emerFont[][13];
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -249,6 +249,7 @@ void GfxOpenGL::startActorDraw(Graphics::Vector3d pos, float yaw, float pitch, f
|
||||||
// TODO find out why shadowMask at device in woods is null
|
// TODO find out why shadowMask at device in woods is null
|
||||||
if (!_currentShadowArray->shadowMask) {
|
if (!_currentShadowArray->shadowMask) {
|
||||||
_currentShadowArray->shadowMask = new byte[_screenWidth * _screenHeight];
|
_currentShadowArray->shadowMask = new byte[_screenWidth * _screenHeight];
|
||||||
|
_currentShadowArray->shadowMaskSize = _screenWidth * _screenHeight;
|
||||||
}
|
}
|
||||||
SectorListType::iterator i = _currentShadowArray->planeList.begin();
|
SectorListType::iterator i = _currentShadowArray->planeList.begin();
|
||||||
Sector *shadowSector = *i;
|
Sector *shadowSector = *i;
|
||||||
|
|
|
@ -355,6 +355,7 @@ void GfxTinyGL::startActorDraw(Graphics::Vector3d pos, float yaw, float pitch, f
|
||||||
// TODO find out why shadowMask at device in woods is null
|
// TODO find out why shadowMask at device in woods is null
|
||||||
if (!_currentShadowArray->shadowMask) {
|
if (!_currentShadowArray->shadowMask) {
|
||||||
_currentShadowArray->shadowMask = new byte[_screenWidth * _screenHeight];
|
_currentShadowArray->shadowMask = new byte[_screenWidth * _screenHeight];
|
||||||
|
_currentShadowArray->shadowMaskSize = _screenWidth * _screenHeight;
|
||||||
}
|
}
|
||||||
assert(_currentShadowArray->shadowMask);
|
assert(_currentShadowArray->shadowMask);
|
||||||
//tglSetShadowColor(255, 255, 255);
|
//tglSetShadowColor(255, 255, 255);
|
||||||
|
@ -400,6 +401,7 @@ void GfxTinyGL::drawShadowPlanes() {
|
||||||
tglEnable(TGL_SHADOW_MASK_MODE);
|
tglEnable(TGL_SHADOW_MASK_MODE);
|
||||||
if (!_currentShadowArray->shadowMask) {
|
if (!_currentShadowArray->shadowMask) {
|
||||||
_currentShadowArray->shadowMask = new byte[_screenWidth * _screenHeight];
|
_currentShadowArray->shadowMask = new byte[_screenWidth * _screenHeight];
|
||||||
|
_currentShadowArray->shadowMaskSize = _screenWidth * _screenHeight;
|
||||||
}
|
}
|
||||||
memset(_currentShadowArray->shadowMask, 0, _screenWidth * _screenHeight);
|
memset(_currentShadowArray->shadowMask, 0, _screenWidth * _screenHeight);
|
||||||
|
|
||||||
|
|
|
@ -46,13 +46,26 @@
|
||||||
#include "engines/grim/localize.h"
|
#include "engines/grim/localize.h"
|
||||||
#include "engines/grim/gfx_tinygl.h"
|
#include "engines/grim/gfx_tinygl.h"
|
||||||
#include "engines/grim/gfx_opengl.h"
|
#include "engines/grim/gfx_opengl.h"
|
||||||
|
#include "engines/grim/object.h"
|
||||||
|
#include "engines/grim/costume.h"
|
||||||
|
#include "engines/grim/material.h"
|
||||||
|
|
||||||
#include "engines/grim/lua/lualib.h"
|
#include "engines/grim/lua/lualib.h"
|
||||||
|
|
||||||
#include "engines/grim/imuse/imuse.h"
|
#include "engines/grim/imuse/imuse.h"
|
||||||
|
|
||||||
|
#include "lua/lobject.h"
|
||||||
|
#include "lua/lstate.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
static const bool color = ObjectManager::registerType<Color>();
|
||||||
|
static const bool luafile = ObjectManager::registerType<LuaFile>();
|
||||||
|
static const bool bitmap = ObjectManager::registerType<Bitmap>();
|
||||||
|
static const bool costume = ObjectManager::registerType<Costume>();
|
||||||
|
static const bool font = ObjectManager::registerType<Font>();
|
||||||
|
static const bool material = ObjectManager::registerType<Material>();
|
||||||
|
|
||||||
static bool g_lua_initialized = false;
|
static bool g_lua_initialized = false;
|
||||||
|
|
||||||
// Entries in the system.controls table
|
// Entries in the system.controls table
|
||||||
|
@ -308,10 +321,10 @@ GrimEngine::~GrimEngine() {
|
||||||
delete[] _controlsState;
|
delete[] _controlsState;
|
||||||
|
|
||||||
for (SceneListType::const_iterator i = _scenes.begin(); i != _scenes.end(); ++i)
|
for (SceneListType::const_iterator i = _scenes.begin(); i != _scenes.end(); ++i)
|
||||||
delete (*i);
|
delete i->_value;
|
||||||
|
|
||||||
for (ActorListType::const_iterator i = _actors.begin(); i != _actors.end(); ++i)
|
for (ActorListType::const_iterator i = _actors.begin(); i != _actors.end(); ++i)
|
||||||
delete (*i);
|
delete i->_value;
|
||||||
|
|
||||||
killPrimitiveObjects();
|
killPrimitiveObjects();
|
||||||
killTextObjects();
|
killTextObjects();
|
||||||
|
@ -362,7 +375,7 @@ Common::Error GrimEngine::run() {
|
||||||
|
|
||||||
g_driver->setupScreen(640, 480, fullscreen);
|
g_driver->setupScreen(640, 480, fullscreen);
|
||||||
|
|
||||||
Bitmap *splash_bm = NULL;
|
BitmapPtr splash_bm;
|
||||||
if (!(_gameFlags & GF_DEMO))
|
if (!(_gameFlags & GF_DEMO))
|
||||||
splash_bm = g_resourceloader->loadBitmap("splash.bm");
|
splash_bm = g_resourceloader->loadBitmap("splash.bm");
|
||||||
|
|
||||||
|
@ -664,12 +677,12 @@ static void cameraPostChangeHandle(int num) {
|
||||||
void GrimEngine::drawPrimitives() {
|
void GrimEngine::drawPrimitives() {
|
||||||
// Draw Primitives
|
// Draw Primitives
|
||||||
for (PrimitiveListType::iterator i = _primitiveObjects.begin(); i != _primitiveObjects.end(); ++i) {
|
for (PrimitiveListType::iterator i = _primitiveObjects.begin(); i != _primitiveObjects.end(); ++i) {
|
||||||
(*i)->draw();
|
i->_value->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw text
|
// Draw text
|
||||||
for (TextListType::iterator i = _textObjects.begin(); i != _textObjects.end(); ++i) {
|
for (TextListType::iterator i = _textObjects.begin(); i != _textObjects.end(); ++i) {
|
||||||
(*i)->draw();
|
i->_value->draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,10 +788,10 @@ void GrimEngine::updateDisplayScene() {
|
||||||
|
|
||||||
// Update actor costumes & sets
|
// Update actor costumes & sets
|
||||||
for (ActorListType::iterator i = _actors.begin(); i != _actors.end(); ++i) {
|
for (ActorListType::iterator i = _actors.begin(); i != _actors.end(); ++i) {
|
||||||
Actor *a = *i;
|
Actor *a = i->_value;
|
||||||
|
|
||||||
// Update the actor's costumes & chores
|
// Update the actor's costumes & chores
|
||||||
g_currentUpdatedActor = *i;
|
g_currentUpdatedActor = i->_value;
|
||||||
// Note that the actor need not be visible to update chores, for example:
|
// Note that the actor need not be visible to update chores, for example:
|
||||||
// when Manny has just brought Meche back he is offscreen several times
|
// when Manny has just brought Meche back he is offscreen several times
|
||||||
// when he needs to perform certain chores
|
// when he needs to perform certain chores
|
||||||
|
@ -789,7 +802,7 @@ void GrimEngine::updateDisplayScene() {
|
||||||
|
|
||||||
// Draw actors
|
// Draw actors
|
||||||
for (ActorListType::iterator i = _actors.begin(); i != _actors.end(); ++i) {
|
for (ActorListType::iterator i = _actors.begin(); i != _actors.end(); ++i) {
|
||||||
Actor *a = *i;
|
Actor *a = i->_value;
|
||||||
if (a->inSet(_currScene->name()) && a->visible())
|
if (a->inSet(_currScene->name()) && a->visible())
|
||||||
a->draw();
|
a->draw();
|
||||||
a->undraw(a->inSet(_currScene->name()) && a->visible());
|
a->undraw(a->inSet(_currScene->name()) && a->visible());
|
||||||
|
@ -955,6 +968,21 @@ void GrimEngine::savegameRestore() {
|
||||||
// free all resource
|
// free all resource
|
||||||
// lock resources
|
// lock resources
|
||||||
|
|
||||||
|
// killActors();
|
||||||
|
// killScenes();
|
||||||
|
// killPrimitiveObjects();
|
||||||
|
// killTextObjects();
|
||||||
|
// killFonts();
|
||||||
|
|
||||||
|
_selectedActor = NULL;
|
||||||
|
_currScene = NULL;
|
||||||
|
|
||||||
|
restoreObjectStates(_savedState);
|
||||||
|
restoreScenes(_savedState);
|
||||||
|
restoreTextObjects(_savedState);
|
||||||
|
restorePrimitives(_savedState);
|
||||||
|
restoreActors(_savedState);
|
||||||
|
|
||||||
//Chore_Restore(_savedState);
|
//Chore_Restore(_savedState);
|
||||||
//Resource_Restore(_savedState);
|
//Resource_Restore(_savedState);
|
||||||
//Text_Restore(_savedState);
|
//Text_Restore(_savedState);
|
||||||
|
@ -969,7 +997,6 @@ void GrimEngine::savegameRestore() {
|
||||||
_savedState->endSection();
|
_savedState->endSection();
|
||||||
// unlock resources
|
// unlock resources
|
||||||
delete _savedState;
|
delete _savedState;
|
||||||
|
|
||||||
//bundle_dofile("patch05.bin");
|
//bundle_dofile("patch05.bin");
|
||||||
|
|
||||||
g_imuse->pause(false);
|
g_imuse->pause(false);
|
||||||
|
@ -977,6 +1004,134 @@ void GrimEngine::savegameRestore() {
|
||||||
printf("GrimEngine::savegameRestore() finished.\n");
|
printf("GrimEngine::savegameRestore() finished.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GrimEngine::restoreActors(SaveGame *state) {
|
||||||
|
state->beginSection('ACTR');
|
||||||
|
|
||||||
|
int32 size = state->readLEUint32();
|
||||||
|
for (int32 i = 0; i < size; ++i) {
|
||||||
|
int32 id = state->readLEUint32();
|
||||||
|
Actor *a = actor(id);
|
||||||
|
if (!a) {
|
||||||
|
a = new Actor();
|
||||||
|
a->_id = id;
|
||||||
|
registerActor(a);
|
||||||
|
if (id > Actor::s_id) {
|
||||||
|
Actor::s_id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a->restoreState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 id = state->readLEUint32();
|
||||||
|
if (id != 0) {
|
||||||
|
_selectedActor = _actors[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
state->endSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::restoreTextObjects(SaveGame *state) {
|
||||||
|
state->beginSection('TEXT');
|
||||||
|
|
||||||
|
sayLineDefaults.disabled = state->readLESint32();
|
||||||
|
sayLineDefaults.fgColor.red() = state->readByte();
|
||||||
|
sayLineDefaults.fgColor.green() = state->readByte();
|
||||||
|
sayLineDefaults.fgColor.blue() = state->readByte();
|
||||||
|
sayLineDefaults.font = g_resourceloader->getFont(state->readString().c_str());
|
||||||
|
sayLineDefaults.height = state->readLESint32();
|
||||||
|
sayLineDefaults.justify = state->readLESint32();
|
||||||
|
sayLineDefaults.width = state->readLESint32();
|
||||||
|
sayLineDefaults.x = state->readLESint32();
|
||||||
|
sayLineDefaults.y = state->readLESint32();
|
||||||
|
|
||||||
|
int32 size = state->readLESint32();
|
||||||
|
for (int32 i = 0; i < size; ++i) {
|
||||||
|
int32 id = state->readLEUint32();
|
||||||
|
TextObject *t = textObject(id);
|
||||||
|
if (!t) {
|
||||||
|
t = new TextObject();
|
||||||
|
t->_id = id;
|
||||||
|
registerTextObject(t);
|
||||||
|
if (id > TextObject::s_id) {
|
||||||
|
TextObject::s_id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t->restoreState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->endSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::restoreScenes(SaveGame *state) {
|
||||||
|
state->beginSection('SET ');
|
||||||
|
|
||||||
|
int32 size = state->readLESint32();
|
||||||
|
for (int32 i = 0; i < size; ++i) {
|
||||||
|
int32 id = state->readLEUint32();
|
||||||
|
Scene *s = scene(id);
|
||||||
|
if (!s) {
|
||||||
|
s = new Scene();
|
||||||
|
s->_id = id;
|
||||||
|
registerScene(s);
|
||||||
|
if (id > Scene::s_id) {
|
||||||
|
Scene::s_id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s->restoreState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
_currScene = scene(state->readLEUint32());
|
||||||
|
|
||||||
|
state->endSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::restorePrimitives(SaveGame *state) {
|
||||||
|
state->beginSection('PRIM');
|
||||||
|
|
||||||
|
int32 size = state->readLESint32();
|
||||||
|
for (int32 i = 0; i < size; ++i) {
|
||||||
|
int32 id = state->readLEUint32();
|
||||||
|
PrimitiveObject *p = primitiveObject(id);
|
||||||
|
if (!p) {
|
||||||
|
p = new PrimitiveObject();
|
||||||
|
p->_id = id;
|
||||||
|
registerPrimitiveObject(p);
|
||||||
|
if (id > PrimitiveObject::s_id) {
|
||||||
|
PrimitiveObject::s_id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p->restoreState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->endSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::restoreObjectStates(SaveGame *state) {
|
||||||
|
state->beginSection('STAT');
|
||||||
|
|
||||||
|
int32 size = state->readLESint32();
|
||||||
|
for (int32 i = 0; i < size; ++i) {
|
||||||
|
int32 id = state->readLEUint32();
|
||||||
|
ObjectState *o = objectState(id);
|
||||||
|
if (!o) {
|
||||||
|
o = new ObjectState();
|
||||||
|
o->_id = id;
|
||||||
|
registerObjectState(o);
|
||||||
|
if (id > ObjectState::s_id) {
|
||||||
|
ObjectState::s_id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
o->restoreState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->endSection();
|
||||||
|
}
|
||||||
|
|
||||||
void GrimEngine::storeSaveGameImage(SaveGame *state) {
|
void GrimEngine::storeSaveGameImage(SaveGame *state) {
|
||||||
int width = 250, height = 188;
|
int width = 250, height = 188;
|
||||||
Bitmap *screenshot;
|
Bitmap *screenshot;
|
||||||
|
@ -1022,7 +1177,8 @@ void GrimEngine::savegameSave() {
|
||||||
|
|
||||||
savegameCallback();
|
savegameCallback();
|
||||||
|
|
||||||
saveFonts(_savedState);
|
saveObjectStates(_savedState);
|
||||||
|
saveScenes(_savedState);
|
||||||
saveTextObjects(_savedState);
|
saveTextObjects(_savedState);
|
||||||
savePrimitives(_savedState);
|
savePrimitives(_savedState);
|
||||||
saveActors(_savedState);
|
saveActors(_savedState);
|
||||||
|
@ -1050,47 +1206,30 @@ void GrimEngine::savegameSave() {
|
||||||
void GrimEngine::saveActors(SaveGame *state) {
|
void GrimEngine::saveActors(SaveGame *state) {
|
||||||
state->beginSection('ACTR');
|
state->beginSection('ACTR');
|
||||||
|
|
||||||
state->writeLESint32(_actors.size());
|
state->writeLEUint32(_actors.size());
|
||||||
for (ActorListType::iterator i = _actors.begin(); i != _actors.end(); ++i) {
|
for (ActorListType::iterator i = _actors.begin(); i != _actors.end(); ++i) {
|
||||||
Actor *a = *i;
|
Actor *a = i->_value;
|
||||||
PointerId ptr = makeIdFromPointer(a);
|
state->writeLEUint32(actorId(a));
|
||||||
state->writeLEUint32(ptr.low);
|
|
||||||
state->writeLEUint32(ptr.hi);
|
|
||||||
a->saveState(state);
|
a->saveState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
state->endSection();
|
if (_selectedActor) {
|
||||||
}
|
state->writeLEUint32(actorId(_selectedActor));
|
||||||
|
} else {
|
||||||
void GrimEngine::saveFonts(SaveGame *state) {
|
state->writeLEUint32(0);
|
||||||
state->beginSection('FONT');
|
|
||||||
|
|
||||||
state->writeLESint32(_fonts.size());
|
|
||||||
for (Common::List<Font *>::iterator i = _fonts.begin(); i != _fonts.end(); ++i) {
|
|
||||||
Font *f = *i;
|
|
||||||
PointerId ptr = makeIdFromPointer(f);
|
|
||||||
state->writeLEUint32(ptr.low);
|
|
||||||
state->writeLEUint32(ptr.hi);
|
|
||||||
Common::String filename = f->getFilename();
|
|
||||||
state->writeLESint32(filename.size());
|
|
||||||
state->write(filename.c_str(), filename.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state->endSection();
|
state->endSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrimEngine::saveTextObjects(SaveGame *state) {
|
void GrimEngine::saveTextObjects(SaveGame *state) {
|
||||||
PointerId ptr;
|
|
||||||
|
|
||||||
state->beginSection('TEXT');
|
state->beginSection('TEXT');
|
||||||
|
|
||||||
state->writeLESint32(sayLineDefaults.disabled);
|
state->writeLESint32(sayLineDefaults.disabled);
|
||||||
state->writeByte(sayLineDefaults.fgColor.red());
|
state->writeByte(sayLineDefaults.fgColor.red());
|
||||||
state->writeByte(sayLineDefaults.fgColor.green());
|
state->writeByte(sayLineDefaults.fgColor.green());
|
||||||
state->writeByte(sayLineDefaults.fgColor.blue());
|
state->writeByte(sayLineDefaults.fgColor.blue());
|
||||||
ptr = makeIdFromPointer(sayLineDefaults.font);
|
state->writeString(sayLineDefaults.font->getFilename());
|
||||||
state->writeLEUint32(ptr.low);
|
|
||||||
state->writeLEUint32(ptr.hi);
|
|
||||||
state->writeLESint32(sayLineDefaults.height);
|
state->writeLESint32(sayLineDefaults.height);
|
||||||
state->writeLESint32(sayLineDefaults.justify);
|
state->writeLESint32(sayLineDefaults.justify);
|
||||||
state->writeLESint32(sayLineDefaults.width);
|
state->writeLESint32(sayLineDefaults.width);
|
||||||
|
@ -1099,10 +1238,8 @@ void GrimEngine::saveTextObjects(SaveGame *state) {
|
||||||
|
|
||||||
state->writeLESint32(_textObjects.size());
|
state->writeLESint32(_textObjects.size());
|
||||||
for (TextListType::iterator i = _textObjects.begin(); i != _textObjects.end(); ++i) {
|
for (TextListType::iterator i = _textObjects.begin(); i != _textObjects.end(); ++i) {
|
||||||
TextObject *t = *i;
|
TextObject *t = i->_value;
|
||||||
ptr = makeIdFromPointer(t);
|
state->writeLEUint32(i->_key);
|
||||||
state->writeLEUint32(ptr.low);
|
|
||||||
state->writeLEUint32(ptr.hi);
|
|
||||||
t->saveState(state);
|
t->saveState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1114,30 +1251,42 @@ void GrimEngine::saveScenes(SaveGame *state) {
|
||||||
|
|
||||||
state->writeLESint32(_scenes.size());
|
state->writeLESint32(_scenes.size());
|
||||||
for (SceneListType::iterator i = _scenes.begin(); i != _scenes.end(); ++i) {
|
for (SceneListType::iterator i = _scenes.begin(); i != _scenes.end(); ++i) {
|
||||||
Scene *s = *i;
|
Scene *s = i->_value;
|
||||||
|
state->writeLEUint32(s->_id);
|
||||||
s->saveState(state);
|
s->saveState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state->writeLEUint32(_currScene->_id);
|
||||||
|
|
||||||
state->endSection();
|
state->endSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrimEngine::savePrimitives(SaveGame *state) {
|
void GrimEngine::savePrimitives(SaveGame *state) {
|
||||||
PointerId ptr;
|
|
||||||
|
|
||||||
state->beginSection('PRIM');
|
state->beginSection('PRIM');
|
||||||
|
|
||||||
state->writeLESint32(_primitiveObjects.size());
|
state->writeLESint32(_primitiveObjects.size());
|
||||||
for (PrimitiveListType::iterator i = _primitiveObjects.begin(); i != _primitiveObjects.end(); ++i) {
|
for (PrimitiveListType::iterator i = _primitiveObjects.begin(); i != _primitiveObjects.end(); ++i) {
|
||||||
PrimitiveObject *p = *i;
|
PrimitiveObject *p = i->_value;
|
||||||
ptr = makeIdFromPointer(p);
|
state->writeLEUint32(p->_id);
|
||||||
state->writeLEUint32(ptr.low);
|
|
||||||
state->writeLEUint32(ptr.hi);
|
|
||||||
p->saveState(state);
|
p->saveState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
state->endSection();
|
state->endSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GrimEngine::saveObjectStates(SaveGame *state) {
|
||||||
|
state->beginSection('STAT');
|
||||||
|
|
||||||
|
state->writeLESint32(_objectStates.size());
|
||||||
|
for (Common::HashMap<int, ObjectState *>::iterator i = _objectStates.begin(); i != _objectStates.end(); ++i) {
|
||||||
|
ObjectState *o = i->_value;
|
||||||
|
state->writeLEUint32(o->_id);
|
||||||
|
o->saveState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->endSection();
|
||||||
|
}
|
||||||
|
|
||||||
void GrimEngine::savegameCallback() {
|
void GrimEngine::savegameCallback() {
|
||||||
lua_Object funcParam1;
|
lua_Object funcParam1;
|
||||||
|
|
||||||
|
@ -1169,8 +1318,8 @@ void GrimEngine::savegameCallback() {
|
||||||
Scene *GrimEngine::findScene(const char *name) {
|
Scene *GrimEngine::findScene(const char *name) {
|
||||||
// Find scene object
|
// Find scene object
|
||||||
for (SceneListType::const_iterator i = scenesBegin(); i != scenesEnd(); ++i) {
|
for (SceneListType::const_iterator i = scenesBegin(); i != scenesEnd(); ++i) {
|
||||||
if (!strcmp((*i)->name(), name))
|
if (!strcmp(i->_value->name(), name))
|
||||||
return *i;
|
return i->_value;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1212,7 +1361,6 @@ void GrimEngine::setScene(const char *name) {
|
||||||
|
|
||||||
void GrimEngine::setScene(Scene *scene) {
|
void GrimEngine::setScene(Scene *scene) {
|
||||||
Scene *lastScene = _currScene;
|
Scene *lastScene = _currScene;
|
||||||
|
|
||||||
_currScene = scene;
|
_currScene = scene;
|
||||||
_currScene->setSoundParameters(20, 127);
|
_currScene->setSoundParameters(20, 127);
|
||||||
// should delete the old scene after setting the new one
|
// should delete the old scene after setting the new one
|
||||||
|
@ -1248,4 +1396,121 @@ bool GrimEngine::getControlState(int num) {
|
||||||
return _controlsState[num];
|
return _controlsState[num];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GrimEngine::registerTextObject(TextObject *t) {
|
||||||
|
_textObjects[t->_id] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::killTextObject(TextObject *t) {
|
||||||
|
_textObjects.erase(t->_id);
|
||||||
|
delete t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::killTextObjects() {
|
||||||
|
while (!_textObjects.empty()) {
|
||||||
|
killTextObject(_textObjects.begin()->_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int GrimEngine::textObjectId(TextObject *t) const {
|
||||||
|
return t->_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextObject *GrimEngine::textObject(int id) const {
|
||||||
|
return _textObjects[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::registerActor(Actor *a) {
|
||||||
|
_actors[a->_id] = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::killActor(Actor *a) {
|
||||||
|
_actors.erase(a->_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::killActors() {
|
||||||
|
// _actors.clear();
|
||||||
|
// while (!_actors.empty()) {
|
||||||
|
// delete _actors.back();
|
||||||
|
// _actors.pop_back();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
int GrimEngine::actorId(Actor *a) const {
|
||||||
|
return a->_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Actor *GrimEngine::actor(int id) const {
|
||||||
|
if (_actors.contains(id)) {
|
||||||
|
return _actors[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::registerObjectState(ObjectState *o) {
|
||||||
|
_objectStates[o->_id] = o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::killObjectState(ObjectState *o) {
|
||||||
|
_objectStates.erase(o->_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::killObjectStates() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int GrimEngine::objectStateId(ObjectState *o) const {
|
||||||
|
return o->_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectState *GrimEngine::objectState(int id) const {
|
||||||
|
return _objectStates[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::registerPrimitiveObject(PrimitiveObject *p) {
|
||||||
|
_primitiveObjects[p->_id] = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::killPrimitiveObject(PrimitiveObject *p) {
|
||||||
|
_primitiveObjects.erase(p->_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::killPrimitiveObjects() {
|
||||||
|
while (!_primitiveObjects.empty()) {
|
||||||
|
PrimitiveObject *p = _primitiveObjects.begin()->_value;
|
||||||
|
killPrimitiveObject(p);
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int GrimEngine::primitiveObjectId(PrimitiveObject *p) const {
|
||||||
|
return p->_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrimitiveObject *GrimEngine::primitiveObject(int id) const {
|
||||||
|
return _primitiveObjects[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::registerScene(Scene *s) {
|
||||||
|
_scenes[s->_id] = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::removeScene(Scene *s) {
|
||||||
|
_scenes.erase(s->_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrimEngine::killScenes() {
|
||||||
|
while (!_scenes.empty()) {
|
||||||
|
removeScene(_scenes.begin()->_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int GrimEngine::sceneId(Scene *s) const {
|
||||||
|
return s->_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene *GrimEngine::scene(int id) const {
|
||||||
|
return _scenes[id];
|
||||||
|
}
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -127,17 +127,18 @@ public:
|
||||||
void makeCurrentSetup(int num);
|
void makeCurrentSetup(int num);
|
||||||
|
|
||||||
// Scene registration
|
// Scene registration
|
||||||
typedef Common::List<Scene *> SceneListType;
|
typedef Common::HashMap<int, Scene *> SceneListType;
|
||||||
SceneListType::const_iterator scenesBegin() const {
|
SceneListType::const_iterator scenesBegin() const {
|
||||||
return _scenes.begin();
|
return _scenes.begin();
|
||||||
}
|
}
|
||||||
SceneListType::const_iterator scenesEnd() const {
|
SceneListType::const_iterator scenesEnd() const {
|
||||||
return _scenes.end();
|
return _scenes.end();
|
||||||
}
|
}
|
||||||
void registerScene(Scene *a) { _scenes.push_back(a); }
|
void registerScene(Scene *a);
|
||||||
void removeScene(Scene *a) {
|
void removeScene(Scene *a);
|
||||||
_scenes.remove(a);
|
void killScenes();
|
||||||
}
|
int sceneId(Scene *s) const;
|
||||||
|
Scene *scene(int id) const;
|
||||||
|
|
||||||
void flagRefreshShadowMask(bool flag) {
|
void flagRefreshShadowMask(bool flag) {
|
||||||
_refreshShadowMask = flag;
|
_refreshShadowMask = flag;
|
||||||
|
@ -156,43 +157,44 @@ public:
|
||||||
_bitmaps.push_back(b);
|
_bitmaps.push_back(b);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
void registerBitmap(Bitmap *bitmap) {
|
||||||
|
_bitmaps.push_back(bitmap);
|
||||||
|
}
|
||||||
void killBitmap(Bitmap *b) { _bitmaps.remove(b); }
|
void killBitmap(Bitmap *b) { _bitmaps.remove(b); }
|
||||||
|
|
||||||
// Actor registration
|
// Actor registration
|
||||||
typedef Common::List<Actor *> ActorListType;
|
typedef Common::HashMap<int, Actor *> ActorListType;
|
||||||
ActorListType::const_iterator actorsBegin() const {
|
ActorListType::const_iterator actorsBegin() const {
|
||||||
return _actors.begin();
|
return _actors.begin();
|
||||||
}
|
}
|
||||||
ActorListType::const_iterator actorsEnd() const {
|
ActorListType::const_iterator actorsEnd() const {
|
||||||
return _actors.end();
|
return _actors.end();
|
||||||
}
|
}
|
||||||
void registerActor(Actor *a) { _actors.push_back(a); }
|
void registerActor(Actor *a);
|
||||||
void killActor(Actor *a) { _actors.remove(a); }
|
void killActor(Actor *a);
|
||||||
|
int actorId(Actor *a) const;
|
||||||
|
Actor *actor(int id) const;
|
||||||
|
|
||||||
void setSelectedActor(Actor *a) { _selectedActor = a; }
|
void setSelectedActor(Actor *a) { _selectedActor = a; }
|
||||||
Actor *selectedActor() { return _selectedActor; }
|
Actor *selectedActor() { return _selectedActor; }
|
||||||
|
void killActors();
|
||||||
|
|
||||||
// Text Object Registration
|
// Text Object Registration
|
||||||
typedef Common::List<TextObject *> TextListType;
|
typedef Common::HashMap<int, TextObject *> TextListType;
|
||||||
TextListType::const_iterator textsBegin() const {
|
TextListType::const_iterator textsBegin() const {
|
||||||
return _textObjects.begin();
|
return _textObjects.begin();
|
||||||
}
|
}
|
||||||
TextListType::const_iterator textsEnd() const {
|
TextListType::const_iterator textsEnd() const {
|
||||||
return _textObjects.end();
|
return _textObjects.end();
|
||||||
}
|
}
|
||||||
void registerTextObject(TextObject *a) { _textObjects.push_back(a); }
|
void registerTextObject(TextObject *a);
|
||||||
void killTextObject(TextObject *a) {
|
void killTextObject(TextObject *a);
|
||||||
_textObjects.remove(a);
|
void killTextObjects();
|
||||||
delete a;
|
int textObjectId(TextObject *t) const;
|
||||||
}
|
TextObject *textObject(int id) const;
|
||||||
void killTextObjects() {
|
|
||||||
while (!_textObjects.empty()) {
|
|
||||||
delete _textObjects.back();
|
|
||||||
_textObjects.pop_back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Primitives Object Registration
|
// Primitives Object Registration
|
||||||
typedef Common::List<PrimitiveObject *> PrimitiveListType;
|
typedef Common::HashMap<int, PrimitiveObject *> PrimitiveListType;
|
||||||
PrimitiveListType::const_iterator primitivesBegin() const {
|
PrimitiveListType::const_iterator primitivesBegin() const {
|
||||||
return _primitiveObjects.begin();
|
return _primitiveObjects.begin();
|
||||||
}
|
}
|
||||||
|
@ -200,29 +202,31 @@ public:
|
||||||
return _primitiveObjects.end();
|
return _primitiveObjects.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerPrimitiveObject(PrimitiveObject *a) { _primitiveObjects.push_back(a); }
|
void registerPrimitiveObject(PrimitiveObject *a);
|
||||||
void killPrimitiveObject(PrimitiveObject *a) {
|
void killPrimitiveObject(PrimitiveObject *a);
|
||||||
_primitiveObjects.remove(a);
|
void killPrimitiveObjects();
|
||||||
}
|
int primitiveObjectId(PrimitiveObject *p) const;
|
||||||
void killPrimitiveObjects() {
|
PrimitiveObject *primitiveObject(int id) const;
|
||||||
while (!_primitiveObjects.empty()) {
|
|
||||||
delete _primitiveObjects.back();
|
|
||||||
_primitiveObjects.pop_back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void registerFont(Font *a) { _fonts.push_back(a); }
|
void registerObjectState(ObjectState *o);
|
||||||
void unregisterFont(Font *a) {
|
void killObjectState(ObjectState *o);
|
||||||
_fonts.remove(a);
|
void killObjectStates();
|
||||||
}
|
int objectStateId(ObjectState *o) const;
|
||||||
|
ObjectState *objectState(int id) const;
|
||||||
|
|
||||||
void savegameSave();
|
void savegameSave();
|
||||||
void savegameRestore();
|
|
||||||
void saveActors(SaveGame *savedState);
|
void saveActors(SaveGame *savedState);
|
||||||
void saveFonts(SaveGame *savedState);
|
|
||||||
void saveTextObjects(SaveGame *savedState);
|
void saveTextObjects(SaveGame *savedState);
|
||||||
void savePrimitives(SaveGame *savedState);
|
void savePrimitives(SaveGame *savedState);
|
||||||
void saveScenes(SaveGame *savedState);
|
void saveScenes(SaveGame *savedState);
|
||||||
|
void saveObjectStates(SaveGame *savedState);
|
||||||
|
|
||||||
|
void savegameRestore();
|
||||||
|
void restoreActors(SaveGame *savedState);
|
||||||
|
void restoreTextObjects(SaveGame *savedState);
|
||||||
|
void restorePrimitives(SaveGame *savedState);
|
||||||
|
void restoreScenes(SaveGame *savedState);
|
||||||
|
void restoreObjectStates(SaveGame *savedState);
|
||||||
|
|
||||||
void savegameCallback();
|
void savegameCallback();
|
||||||
static void savegameReadStream(void *data, int32 size);
|
static void savegameReadStream(void *data, int32 size);
|
||||||
|
@ -274,8 +278,8 @@ private:
|
||||||
Actor *_selectedActor;
|
Actor *_selectedActor;
|
||||||
TextListType _textObjects;
|
TextListType _textObjects;
|
||||||
PrimitiveListType _primitiveObjects;
|
PrimitiveListType _primitiveObjects;
|
||||||
Common::List<Font *> _fonts;
|
|
||||||
Common::List<Bitmap *> _bitmaps;
|
Common::List<Bitmap *> _bitmaps;
|
||||||
|
Common::HashMap<int, ObjectState *> _objectStates;
|
||||||
|
|
||||||
int _gameFlags;
|
int _gameFlags;
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,8 @@
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
KeyframeAnim::KeyframeAnim(const char *fname, const char *data, int len) {
|
KeyframeAnim::KeyframeAnim(const char *fname, const char *data, int len) :
|
||||||
|
Object() {
|
||||||
_fname = fname;
|
_fname = fname;
|
||||||
|
|
||||||
if (len >= 4 && READ_BE_UINT32(data) == MKID_BE('FYEK'))
|
if (len >= 4 && READ_BE_UINT32(data) == MKID_BE('FYEK'))
|
||||||
|
@ -140,6 +141,7 @@ KeyframeAnim::~KeyframeAnim() {
|
||||||
for (int i = 0; i < _numJoints; i++)
|
for (int i = 0; i < _numJoints; i++)
|
||||||
delete _nodes[i];
|
delete _nodes[i];
|
||||||
delete[] _markers;
|
delete[] _markers;
|
||||||
|
g_resourceloader->uncacheKeyframe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyframeAnim::animate(Model::HierNode *nodes, float time, int priority1, int priority2) const {
|
void KeyframeAnim::animate(Model::HierNode *nodes, float time, int priority1, int priority2) const {
|
||||||
|
|
|
@ -27,10 +27,12 @@
|
||||||
#define GRIM_KEYFRAME_H
|
#define GRIM_KEYFRAME_H
|
||||||
|
|
||||||
#include "engines/grim/model.h"
|
#include "engines/grim/model.h"
|
||||||
|
#include "engines/grim/object.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
class KeyframeAnim {
|
class KeyframeAnim : public Object {
|
||||||
|
GRIM_OBJECT(KeyFrameAnim)
|
||||||
public:
|
public:
|
||||||
KeyframeAnim(const char *filename, const char *data, int len);
|
KeyframeAnim(const char *filename, const char *data, int len);
|
||||||
~KeyframeAnim();
|
~KeyframeAnim();
|
||||||
|
|
|
@ -32,7 +32,8 @@ namespace Grim {
|
||||||
// A new define that'll be around when theres a configure script :)
|
// A new define that'll be around when theres a configure script :)
|
||||||
#undef DEBUG_VERBOSE
|
#undef DEBUG_VERBOSE
|
||||||
|
|
||||||
LipSync::LipSync(const char *filename, const char *data, int len) {
|
LipSync::LipSync(const char *filename, const char *data, int len) :
|
||||||
|
Object() {
|
||||||
_fname = filename;
|
_fname = filename;
|
||||||
uint16 readPhoneme;
|
uint16 readPhoneme;
|
||||||
int j;
|
int j;
|
||||||
|
@ -76,6 +77,7 @@ LipSync::LipSync(const char *filename, const char *data, int len) {
|
||||||
|
|
||||||
LipSync::~LipSync() {
|
LipSync::~LipSync() {
|
||||||
delete[] _entries;
|
delete[] _entries;
|
||||||
|
g_resourceloader->uncacheLipSync(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
int LipSync::getAnim(int pos) {
|
int LipSync::getAnim(int pos) {
|
||||||
|
@ -100,6 +102,10 @@ int LipSync::getAnim(int pos) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *LipSync::filename() const {
|
||||||
|
return _fname.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
const LipSync::PhonemeAnim LipSync::_animTable[] = {
|
const LipSync::PhonemeAnim LipSync::_animTable[] = {
|
||||||
{0x005F, 0}, {0x0251, 1}, {0x0061, 1}, {0x00E6, 1}, {0x028C, 8},
|
{0x005F, 0}, {0x0251, 1}, {0x0061, 1}, {0x00E6, 1}, {0x028C, 8},
|
||||||
{0x0254, 1}, {0x0259, 1}, {0x0062, 6}, {0x02A7, 2}, {0x0064, 2},
|
{0x0254, 1}, {0x0259, 1}, {0x0062, 6}, {0x02A7, 2}, {0x0064, 2},
|
||||||
|
|
|
@ -27,10 +27,11 @@
|
||||||
#define GRIM_LIPSYNC_H
|
#define GRIM_LIPSYNC_H
|
||||||
|
|
||||||
#include "engines/grim/resource.h"
|
#include "engines/grim/resource.h"
|
||||||
|
#include "engines/grim/object.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
class LipSync {
|
class LipSync : public Object {
|
||||||
public:
|
public:
|
||||||
LipSync(const char *filename, const char *data, int len);
|
LipSync(const char *filename, const char *data, int len);
|
||||||
~LipSync();
|
~LipSync();
|
||||||
|
@ -42,6 +43,9 @@ public:
|
||||||
|
|
||||||
int getAnim(int pos);
|
int getAnim(int pos);
|
||||||
bool isValid() { return _numEntries > 0; }
|
bool isValid() { return _numEntries > 0; }
|
||||||
|
const char *filename() const;
|
||||||
|
|
||||||
|
int typeId() const { return 16; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LipEntry *_entries;
|
LipEntry *_entries;
|
||||||
|
|
|
@ -75,6 +75,7 @@ static void checkCparams(int32 nParams) {
|
||||||
static lua_Object put_luaObject(TObject *o) {
|
static lua_Object put_luaObject(TObject *o) {
|
||||||
luaD_openstack((lua_state->stack.top - lua_state->stack.stack) - lua_state->Cstack.base);
|
luaD_openstack((lua_state->stack.top - lua_state->stack.stack) - lua_state->Cstack.base);
|
||||||
lua_state->stack.stack[lua_state->Cstack.base++] = *o;
|
lua_state->stack.stack[lua_state->Cstack.base++] = *o;
|
||||||
|
|
||||||
return lua_state->Cstack.base; // this is +1 real position (see Ref)
|
return lua_state->Cstack.base; // this is +1 real position (see Ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,15 +415,21 @@ int32 lua_setlocal(lua_Function func, int32 local_number) {
|
||||||
void lua_funcinfo(lua_Object func, const char **filename, int32 *linedefined) {
|
void lua_funcinfo(lua_Object func, const char **filename, int32 *linedefined) {
|
||||||
if (!lua_isfunction(func))
|
if (!lua_isfunction(func))
|
||||||
lua_error("API - `funcinfo' called with a non-function value");
|
lua_error("API - `funcinfo' called with a non-function value");
|
||||||
else {
|
else {
|
||||||
TObject *f = luaA_protovalue(Address(func));
|
//FIXME: After loading a savegame tfvalue(f) will point to a
|
||||||
if (normalized_type(f) == LUA_T_PROTO) {
|
// TProtoFunc which was deleted by lua_close(), called by lua_restore(). so
|
||||||
*filename = tfvalue(f)->fileName->str;
|
// it will crash. Anyway commenting it doesn't seem to cause any harm aside the
|
||||||
*linedefined = tfvalue(f)->lineDefined;
|
// fact that an eventual lua stack will not report the file names.
|
||||||
} else {
|
// So it is commented until we come up with a fix.
|
||||||
|
|
||||||
|
// TObject *f = luaA_protovalue(Address(func));
|
||||||
|
// if (normalized_type(f) == LUA_T_PROTO) {
|
||||||
|
// *filename = tfvalue(f)->fileName->str;
|
||||||
|
// *linedefined = tfvalue(f)->lineDefined;
|
||||||
|
// } else {
|
||||||
*filename = "(C)";
|
*filename = "(C)";
|
||||||
*linedefined = -1;
|
*linedefined = -1;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -320,7 +320,7 @@ void lua_error(const char *s) {
|
||||||
static void do_callinc(int32 nResults) {
|
static void do_callinc(int32 nResults) {
|
||||||
StkId base = lua_state->Cstack.base;
|
StkId base = lua_state->Cstack.base;
|
||||||
luaD_call(base + 1, nResults);
|
luaD_call(base + 1, nResults);
|
||||||
lua_state->Cstack.lua2C = base; // position of the luaM_new results
|
lua_state->Cstack.lua2C = base; // position of the luaM_new results
|
||||||
lua_state->Cstack.num = (lua_state->stack.top - lua_state->stack.stack) - base; // number of results
|
lua_state->Cstack.num = (lua_state->stack.top - lua_state->stack.stack) - base; // number of results
|
||||||
lua_state->Cstack.base = base + lua_state->Cstack.num; // incorporate results on lua_state->stack.stack/
|
lua_state->Cstack.base = base + lua_state->Cstack.num; // incorporate results on lua_state->stack.stack/
|
||||||
}
|
}
|
||||||
|
@ -373,10 +373,10 @@ static int32 protectedparser(ZIO *z, int32 bin) {
|
||||||
}
|
}
|
||||||
lua_state->errorJmp = oldErr;
|
lua_state->errorJmp = oldErr;
|
||||||
if (status)
|
if (status)
|
||||||
return 1; // error code
|
return 1; // error code
|
||||||
if (tf == NULL)
|
if (tf == NULL)
|
||||||
return 2; // 'natural' end
|
return 2; // 'natural' end
|
||||||
luaD_adjusttop(lua_state->Cstack.base + 1); // one slot for the pseudo-function
|
luaD_adjusttop(lua_state->Cstack.base + 1); // one slot for the pseudo-function
|
||||||
lua_state->stack.stack[lua_state->Cstack.base].ttype = LUA_T_PROTO;
|
lua_state->stack.stack[lua_state->Cstack.base].ttype = LUA_T_PROTO;
|
||||||
lua_state->stack.stack[lua_state->Cstack.base].value.tf = tf;
|
lua_state->stack.stack[lua_state->Cstack.base].value.tf = tf;
|
||||||
luaV_closure(0);
|
luaV_closure(0);
|
||||||
|
@ -391,7 +391,7 @@ static int32 do_main(ZIO *z, int32 bin) {
|
||||||
if (status == 1)
|
if (status == 1)
|
||||||
return 1; // error
|
return 1; // error
|
||||||
else if (status == 2)
|
else if (status == 2)
|
||||||
return 0; // 'natural' end
|
return 0; // 'natural' end
|
||||||
else {
|
else {
|
||||||
int32 newelems2 = 2 * (nblocks - old_blocks);
|
int32 newelems2 = 2 * (nblocks - old_blocks);
|
||||||
GCthreshold += newelems2;
|
GCthreshold += newelems2;
|
||||||
|
|
|
@ -100,6 +100,46 @@ void LuaFile::seek(int32 pos, int whence) {
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LuaFile::saveState(SaveGame *state) const {
|
||||||
|
state->writeString(_name);
|
||||||
|
state->writeString(_filename);
|
||||||
|
|
||||||
|
if (_in) {
|
||||||
|
state->writeLESint32(1);
|
||||||
|
} else {
|
||||||
|
state->writeLESint32(0);
|
||||||
|
}
|
||||||
|
if (_out) {
|
||||||
|
state->writeLESint32(1);
|
||||||
|
} else {
|
||||||
|
state->writeLESint32(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->writeLESint32(_stdin);
|
||||||
|
state->writeLESint32(_stdout);
|
||||||
|
state->writeLESint32(_stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaFile::restoreState(SaveGame *state) {
|
||||||
|
_name = state->readString();;
|
||||||
|
_filename = state->readString();
|
||||||
|
|
||||||
|
if (state->readLESint32()) {
|
||||||
|
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
||||||
|
_in = saveFileMan->openForLoading(_filename.c_str());
|
||||||
|
}
|
||||||
|
if (state->readLESint32()) {
|
||||||
|
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
||||||
|
_out = saveFileMan->openForSaving(_filename.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
_stdin = state->readLESint32();
|
||||||
|
_stdout = state->readLESint32();
|
||||||
|
_stderr = state->readLESint32();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int32 gettag(int32 i) {
|
static int32 gettag(int32 i) {
|
||||||
return (int32)lua_getnumber(lua_getparam(i));
|
return (int32)lua_getnumber(lua_getparam(i));
|
||||||
}
|
}
|
||||||
|
@ -179,6 +219,7 @@ static void io_readfrom() {
|
||||||
else {
|
else {
|
||||||
current = new LuaFile();
|
current = new LuaFile();
|
||||||
current->_in = inFile;
|
current->_in = inFile;
|
||||||
|
current->_filename = s;
|
||||||
}
|
}
|
||||||
if (!current) {
|
if (!current) {
|
||||||
delete current;
|
delete current;
|
||||||
|
@ -217,6 +258,7 @@ static void io_writeto() {
|
||||||
}
|
}
|
||||||
current = new LuaFile();
|
current = new LuaFile();
|
||||||
current->_out = outFile;
|
current->_out = outFile;
|
||||||
|
current->_filename = s;
|
||||||
setreturn(current, FOUTPUT);
|
setreturn(current, FOUTPUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,6 +285,7 @@ static void io_appendto() {
|
||||||
outFile->write(buf, size);
|
outFile->write(buf, size);
|
||||||
LuaFile *current = new LuaFile();
|
LuaFile *current = new LuaFile();
|
||||||
current->_out = outFile;
|
current->_out = outFile;
|
||||||
|
current->_filename = s;
|
||||||
setreturn(current, FOUTPUT);
|
setreturn(current, FOUTPUT);
|
||||||
}
|
}
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
|
@ -351,7 +394,7 @@ static void lua_printstack() {
|
||||||
case 't':
|
case 't':
|
||||||
sprintf(buf, "`%s' tag method", name);
|
sprintf(buf, "`%s' tag method", name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
if (linedefined == 0)
|
if (linedefined == 0)
|
||||||
sprintf(buf, "main of %s", filename);
|
sprintf(buf, "main of %s", filename);
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "engines/grim/lua/lobject.h"
|
#include "engines/grim/lua/lobject.h"
|
||||||
#include "engines/grim/lua/lua.h"
|
#include "engines/grim/lua/lua.h"
|
||||||
|
#include "engines/grim/lua/lstring.h"
|
||||||
|
#include "engines/grim/lua/lstate.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
@ -78,4 +80,23 @@ void luaO_insertlist(GCnode *root, GCnode *node) {
|
||||||
node->marked = 0;
|
node->marked = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void luaO_resetObject(void *o) {
|
||||||
|
TaggedString *tempString;
|
||||||
|
if (string_root) {
|
||||||
|
for (int i = 0; i < NUM_HASHS; i++) {
|
||||||
|
stringtable *tempStringTable = &string_root[i];
|
||||||
|
for (int l = 0; l < tempStringTable->size; l++) {
|
||||||
|
if (tempStringTable->hash[l] && tempStringTable->hash[l] != &EMPTY) {
|
||||||
|
tempString = tempStringTable->hash[l];
|
||||||
|
if (tempString->constindex == -1) {
|
||||||
|
if (tempString->globalval.value.ts == o) {
|
||||||
|
tempString->globalval.value.ts = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -142,6 +142,8 @@ int32 luaO_redimension(int32 oldsize);
|
||||||
int luaO_findstring(const char *name, const char *list[]);
|
int luaO_findstring(const char *name, const char *list[]);
|
||||||
void luaO_insertlist(GCnode *root, GCnode *node);
|
void luaO_insertlist(GCnode *root, GCnode *node);
|
||||||
|
|
||||||
|
void luaO_resetObject(void *o);
|
||||||
|
|
||||||
#define luaO_memup(d, s, n) memmove(d, s, n)
|
#define luaO_memup(d, s, n) memmove(d, s, n)
|
||||||
#define luaO_memdown(d, s, n) memmove(d, s, n)
|
#define luaO_memdown(d, s, n) memmove(d, s, n)
|
||||||
|
|
||||||
|
|
|
@ -265,7 +265,7 @@ void lua_Restore(RestoreStream restoreStream, RestoreSint32 restoreSint32, Resto
|
||||||
restoreObjectValue(&obj, restoreSint32, restoreUint32);
|
restoreObjectValue(&obj, restoreSint32, restoreUint32);
|
||||||
int32 length = restoreSint32();
|
int32 length = restoreSint32();
|
||||||
restoreStream(tempStringBuffer, length);
|
restoreStream(tempStringBuffer, length);
|
||||||
tempStringBuffer[length] = 0;
|
tempStringBuffer[length] = '\0';
|
||||||
tempString = luaS_new(tempStringBuffer);
|
tempString = luaS_new(tempStringBuffer);
|
||||||
tempString->globalval = obj;
|
tempString->globalval = obj;
|
||||||
} else {
|
} else {
|
||||||
|
@ -273,10 +273,30 @@ void lua_Restore(RestoreStream restoreStream, RestoreSint32 restoreSint32, Resto
|
||||||
lua_Type tag = (lua_Type)restoreSint32();
|
lua_Type tag = (lua_Type)restoreSint32();
|
||||||
ptr.low = restoreUint32();
|
ptr.low = restoreUint32();
|
||||||
ptr.hi = restoreUint32();
|
ptr.hi = restoreUint32();
|
||||||
|
void *pointer = 0;
|
||||||
|
if (restoreUint32()) {
|
||||||
|
int x = restoreUint32();
|
||||||
|
if (x == 1) {
|
||||||
|
int id = restoreUint32();
|
||||||
|
pointer = g_grim->actor(id);
|
||||||
|
} else if (x == 2) {
|
||||||
|
int id = restoreUint32();
|
||||||
|
pointer = g_grim->textObject(id);
|
||||||
|
} else if (x == 3) {
|
||||||
|
int id = restoreUint32();
|
||||||
|
pointer = g_grim->objectState(id);
|
||||||
|
} else {
|
||||||
|
pointer = ObjectManager::restoreObject(g_grim->_savedState);
|
||||||
|
}
|
||||||
|
if (!pointer) {
|
||||||
|
pointer = makePointerFromId(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (tag == 0)
|
if (tag == 0)
|
||||||
tempString = luaS_createudata((void *)makePointerFromId(ptr), LUA_ANYTAG);
|
tempString = luaS_createudata(pointer, LUA_ANYTAG);
|
||||||
else
|
else
|
||||||
tempString = luaS_createudata((void *)makePointerFromId(ptr), tag);
|
tempString = luaS_createudata(pointer, tag);
|
||||||
if (restoreCallbackPtr) {
|
if (restoreCallbackPtr) {
|
||||||
ptr = makeIdFromPointer(tempString->globalval.value.ts);
|
ptr = makeIdFromPointer(tempString->globalval.value.ts);
|
||||||
ptr = restoreCallbackPtr(tempString->globalval.ttype, ptr, restoreSint32);
|
ptr = restoreCallbackPtr(tempString->globalval.ttype, ptr, restoreSint32);
|
||||||
|
@ -293,6 +313,7 @@ void lua_Restore(RestoreStream restoreStream, RestoreSint32 restoreSint32, Resto
|
||||||
|
|
||||||
int32 l;
|
int32 l;
|
||||||
Closure *tempClosure;
|
Closure *tempClosure;
|
||||||
|
GCnode *prevClosure = &rootcl;
|
||||||
arraysObj = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayClosuresCount);
|
arraysObj = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayClosuresCount);
|
||||||
arrayClosures = arraysObj;
|
arrayClosures = arraysObj;
|
||||||
for (i = 0; i < arrayClosuresCount; i++) {
|
for (i = 0; i < arrayClosuresCount; i++) {
|
||||||
|
@ -300,7 +321,8 @@ void lua_Restore(RestoreStream restoreStream, RestoreSint32 restoreSint32, Resto
|
||||||
arraysObj->idObj.hi = restoreSint32();
|
arraysObj->idObj.hi = restoreSint32();
|
||||||
int32 countElements = restoreSint32();
|
int32 countElements = restoreSint32();
|
||||||
tempClosure = (Closure *)luaM_malloc((countElements * sizeof(TObject)) + sizeof(Closure));
|
tempClosure = (Closure *)luaM_malloc((countElements * sizeof(TObject)) + sizeof(Closure));
|
||||||
luaO_insertlist(&rootcl, (GCnode *)tempClosure);
|
luaO_insertlist(prevClosure, (GCnode *)tempClosure);
|
||||||
|
prevClosure = (GCnode *)tempClosure;
|
||||||
|
|
||||||
tempClosure->nelems = countElements;
|
tempClosure->nelems = countElements;
|
||||||
for (l = 0; l <= tempClosure->nelems; l++) {
|
for (l = 0; l <= tempClosure->nelems; l++) {
|
||||||
|
@ -311,6 +333,7 @@ void lua_Restore(RestoreStream restoreStream, RestoreSint32 restoreSint32, Resto
|
||||||
}
|
}
|
||||||
|
|
||||||
Hash *tempHash;
|
Hash *tempHash;
|
||||||
|
GCnode *prevHash = &roottable;
|
||||||
arraysObj = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayHashTablesCount);
|
arraysObj = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayHashTablesCount);
|
||||||
arrayHashTables = arraysObj;
|
arrayHashTables = arraysObj;
|
||||||
for (i = 0; i < arrayHashTablesCount; i++) {
|
for (i = 0; i < arrayHashTablesCount; i++) {
|
||||||
|
@ -321,7 +344,8 @@ void lua_Restore(RestoreStream restoreStream, RestoreSint32 restoreSint32, Resto
|
||||||
tempHash->nuse = restoreSint32();
|
tempHash->nuse = restoreSint32();
|
||||||
tempHash->htag = restoreSint32();
|
tempHash->htag = restoreSint32();
|
||||||
tempHash->node = hashnodecreate(tempHash->nhash);
|
tempHash->node = hashnodecreate(tempHash->nhash);
|
||||||
luaO_insertlist(&roottable, (GCnode *)tempHash);
|
luaO_insertlist(prevHash, (GCnode *)tempHash);
|
||||||
|
prevHash = (GCnode *)tempHash;
|
||||||
|
|
||||||
for (l = 0; l < tempHash->nuse; l++) {
|
for (l = 0; l < tempHash->nuse; l++) {
|
||||||
restoreObjectValue(&tempHash->node[l].ref, restoreSint32, restoreUint32);
|
restoreObjectValue(&tempHash->node[l].ref, restoreSint32, restoreUint32);
|
||||||
|
@ -332,20 +356,26 @@ void lua_Restore(RestoreStream restoreStream, RestoreSint32 restoreSint32, Resto
|
||||||
}
|
}
|
||||||
|
|
||||||
TProtoFunc *tempProtoFunc;
|
TProtoFunc *tempProtoFunc;
|
||||||
|
GCnode *oldProto = &rootproto;
|
||||||
arrayProtoFuncs = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayProtoFuncsCount);
|
arrayProtoFuncs = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayProtoFuncsCount);
|
||||||
arraysObj = arrayProtoFuncs;
|
arraysObj = arrayProtoFuncs;
|
||||||
for (i = 0; i < arrayProtoFuncsCount; i++) {
|
for (i = 0; i < arrayProtoFuncsCount; i++) {
|
||||||
arraysObj->idObj.low = restoreSint32();
|
arraysObj->idObj.low = restoreSint32();
|
||||||
arraysObj->idObj.hi = restoreSint32();
|
arraysObj->idObj.hi = restoreSint32();
|
||||||
tempProtoFunc = luaM_new(TProtoFunc);
|
tempProtoFunc = luaM_new(TProtoFunc);
|
||||||
luaO_insertlist(&rootproto, (GCnode *)tempProtoFunc);
|
luaO_insertlist(oldProto, (GCnode *)tempProtoFunc);
|
||||||
|
oldProto = (GCnode *)tempProtoFunc;
|
||||||
PointerId ptr;
|
PointerId ptr;
|
||||||
ptr.low = restoreSint32();
|
ptr.low = restoreSint32();
|
||||||
ptr.hi = restoreSint32();
|
ptr.hi = restoreSint32();
|
||||||
tempProtoFunc->fileName = (TaggedString *)makePointerFromId(ptr);
|
tempProtoFunc->fileName = (TaggedString *)makePointerFromId(ptr);
|
||||||
tempProtoFunc->lineDefined = restoreSint32();
|
tempProtoFunc->lineDefined = restoreSint32();
|
||||||
tempProtoFunc->nconsts = restoreSint32();
|
tempProtoFunc->nconsts = restoreSint32();
|
||||||
tempProtoFunc->consts = (TObject *)luaM_malloc(tempProtoFunc->nconsts * sizeof(TObject));
|
if (tempProtoFunc->nconsts > 0) {
|
||||||
|
tempProtoFunc->consts = (TObject *)luaM_malloc(tempProtoFunc->nconsts * sizeof(TObject));
|
||||||
|
} else {
|
||||||
|
tempProtoFunc->consts = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (l = 0; l < tempProtoFunc->nconsts; l++) {
|
for (l = 0; l < tempProtoFunc->nconsts; l++) {
|
||||||
restoreObjectValue(&tempProtoFunc->consts[l], restoreSint32, restoreUint32);
|
restoreObjectValue(&tempProtoFunc->consts[l], restoreSint32, restoreUint32);
|
||||||
|
@ -389,7 +419,6 @@ void lua_Restore(RestoreStream restoreStream, RestoreSint32 restoreSint32, Resto
|
||||||
tempObj.ttype = LUA_T_STRING;
|
tempObj.ttype = LUA_T_STRING;
|
||||||
recreateObj(&tempObj);
|
recreateObj(&tempObj);
|
||||||
tempProtoFunc->fileName = (TaggedString *)tempObj.value.ts;
|
tempProtoFunc->fileName = (TaggedString *)tempObj.value.ts;
|
||||||
|
|
||||||
for (i = 0; i < tempProtoFunc->nconsts; i++) {
|
for (i = 0; i < tempProtoFunc->nconsts; i++) {
|
||||||
recreateObj(&tempProtoFunc->consts[i]);
|
recreateObj(&tempProtoFunc->consts[i]);
|
||||||
}
|
}
|
||||||
|
@ -454,22 +483,30 @@ void lua_Restore(RestoreStream restoreStream, RestoreSint32 restoreSint32, Resto
|
||||||
recreateObj(&errorim);
|
recreateObj(&errorim);
|
||||||
|
|
||||||
IMtable_size = restoreSint32();
|
IMtable_size = restoreSint32();
|
||||||
IMtable = (IM *)luaM_malloc(IMtable_size * sizeof(IM));
|
if (IMtable_size > 0) {
|
||||||
for (i = 0; i < IMtable_size; i++) {
|
IMtable = (IM *)luaM_malloc(IMtable_size * sizeof(IM));
|
||||||
IM *im = &IMtable[i];
|
for (i = 0; i < IMtable_size; i++) {
|
||||||
for (l = 0; l < IM_N; l++) {
|
IM *im = &IMtable[i];
|
||||||
restoreObjectValue(&im->int_method[l], restoreSint32, restoreUint32);
|
for (l = 0; l < IM_N; l++) {
|
||||||
recreateObj(&im->int_method[l]);
|
restoreObjectValue(&im->int_method[l], restoreSint32, restoreUint32);
|
||||||
|
recreateObj(&im->int_method[l]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
IMtable = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_tag = restoreSint32();
|
last_tag = restoreSint32();
|
||||||
refSize = restoreSint32();
|
refSize = restoreSint32();
|
||||||
refArray = (ref *)luaM_malloc(refSize * sizeof(ref));
|
if (refSize > 0) {
|
||||||
for (i = 0; i < refSize; i++) {
|
refArray = (ref *)luaM_malloc(refSize * sizeof(ref));
|
||||||
restoreObjectValue(&refArray[i].o, restoreSint32, restoreUint32);
|
for (i = 0; i < refSize; i++) {
|
||||||
recreateObj(&refArray[i].o);
|
restoreObjectValue(&refArray[i].o, restoreSint32, restoreUint32);
|
||||||
refArray[i].status = (Status)restoreSint32();
|
recreateObj(&refArray[i].o);
|
||||||
|
refArray[i].status = (Status)restoreSint32();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
refArray = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GCthreshold = restoreSint32();
|
GCthreshold = restoreSint32();
|
||||||
|
@ -501,10 +538,18 @@ void lua_Restore(RestoreStream restoreStream, RestoreSint32 restoreSint32, Resto
|
||||||
}
|
}
|
||||||
int32 countTasks = restoreSint32();
|
int32 countTasks = restoreSint32();
|
||||||
if (countTasks) {
|
if (countTasks) {
|
||||||
|
lua_Task *task;
|
||||||
for (i = 0; i < countTasks; i++) {
|
for (i = 0; i < countTasks; i++) {
|
||||||
lua_Task *task = state->task;
|
if (i == 0) {
|
||||||
task = luaM_new(lua_Task);
|
task = state->task = luaM_new(lua_Task);
|
||||||
lua_taskinit(task, NULL, 0, 0);
|
lua_taskinit(task, NULL, 0, 0);
|
||||||
|
} else {
|
||||||
|
lua_Task *t = luaM_new(lua_Task);
|
||||||
|
lua_taskinit(t, NULL, 0, 0);
|
||||||
|
task->next = t;
|
||||||
|
task = t;
|
||||||
|
}
|
||||||
|
|
||||||
task->S = &state->stack;
|
task->S = &state->stack;
|
||||||
|
|
||||||
TObject tempObj;
|
TObject tempObj;
|
||||||
|
@ -527,7 +572,7 @@ void lua_Restore(RestoreStream restoreStream, RestoreSint32 restoreSint32, Resto
|
||||||
task->some_results = restoreSint32();
|
task->some_results = restoreSint32();
|
||||||
task->some_flag = restoreSint32();
|
task->some_flag = restoreSint32();
|
||||||
int32 pcOffset = restoreSint32();
|
int32 pcOffset = restoreSint32();
|
||||||
task->pc = state->task->tf->code + pcOffset;
|
task->pc = task->tf->code + pcOffset;
|
||||||
task->aux = restoreSint32();
|
task->aux = restoreSint32();
|
||||||
task->consts = task->tf->consts;
|
task->consts = task->tf->consts;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "engines/grim/lua/lopcodes.h"
|
#include "engines/grim/lua/lopcodes.h"
|
||||||
#include "engines/grim/lua/lstring.h"
|
#include "engines/grim/lua/lstring.h"
|
||||||
#include "engines/grim/lua/lua.h"
|
#include "engines/grim/lua/lua.h"
|
||||||
|
#include "engines/grim/actor.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
@ -241,6 +242,26 @@ void lua_Save(SaveStream saveStream, SaveSint32 saveSint32, SaveUint32 saveUint3
|
||||||
tempString->globalval.value.ts = (TaggedString *)makePointerFromId(ptr);
|
tempString->globalval.value.ts = (TaggedString *)makePointerFromId(ptr);
|
||||||
}
|
}
|
||||||
saveObjectValue((TObject *)&tempString->globalval, saveSint32, saveUint32);
|
saveObjectValue((TObject *)&tempString->globalval, saveSint32, saveUint32);
|
||||||
|
if (tempString->globalval.value.ts) {
|
||||||
|
saveUint32(1);
|
||||||
|
Object *o = (Object *)tempString->globalval.value.ts;
|
||||||
|
|
||||||
|
if (Actor *a = dynamic_cast<Actor *>(o)) {
|
||||||
|
saveUint32(1);
|
||||||
|
saveUint32(g_grim->actorId(a));
|
||||||
|
} else if (TextObject *t = dynamic_cast<TextObject *>(o)) {
|
||||||
|
saveUint32(2);
|
||||||
|
saveUint32(g_grim->textObjectId(t));
|
||||||
|
} else if (ObjectState *s = dynamic_cast<ObjectState *>(o)) {
|
||||||
|
saveUint32(3);
|
||||||
|
saveUint32(g_grim->objectStateId(s));
|
||||||
|
} else {
|
||||||
|
saveUint32(4);
|
||||||
|
ObjectManager::saveObject(g_grim->_savedState, o);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
saveUint32(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,7 +379,7 @@ void lua_Save(SaveStream saveStream, SaveSint32 saveSint32, SaveUint32 saveUint3
|
||||||
int32 countStates = 0, currentState = 0;
|
int32 countStates = 0, currentState = 0;
|
||||||
LState *state = lua_rootState;
|
LState *state = lua_rootState;
|
||||||
while (state) {
|
while (state) {
|
||||||
if (lua_rootState == state)
|
if (lua_state == state)
|
||||||
currentState = countStates;
|
currentState = countStates;
|
||||||
countStates++;
|
countStates++;
|
||||||
state = state->next;
|
state = state->next;
|
||||||
|
|
|
@ -371,7 +371,7 @@ static void add_localvar (TaggedString *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** dotted variables <a.x> must be stored like regular indexed vars <a["x"]>
|
** dotted variables <a.x> must be stored like regular indexed vars <a["x"]>
|
||||||
*/
|
*/
|
||||||
static vardesc var2store (vardesc var)
|
static vardesc var2store (vardesc var)
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "common/sys.h"
|
#include "common/sys.h"
|
||||||
#include "common/str.h"
|
#include "common/str.h"
|
||||||
|
#include "engines/grim/object.h"
|
||||||
|
|
||||||
#ifndef GRIM_LUA_H
|
#ifndef GRIM_LUA_H
|
||||||
#define GRIM_LUA_H
|
#define GRIM_LUA_H
|
||||||
|
@ -41,9 +42,11 @@ struct PointerId {
|
||||||
PointerId makeIdFromPointer(void *ptr);
|
PointerId makeIdFromPointer(void *ptr);
|
||||||
void *makePointerFromId(PointerId ptr);
|
void *makePointerFromId(PointerId ptr);
|
||||||
|
|
||||||
class LuaFile {
|
class LuaFile : public Object {
|
||||||
|
GRIM_OBJECT(LuaFile)
|
||||||
public:
|
public:
|
||||||
Common::String _name;
|
Common::String _name;
|
||||||
|
Common::String _filename;
|
||||||
Common::SeekableReadStream *_in;
|
Common::SeekableReadStream *_in;
|
||||||
Common::WriteStream *_out;
|
Common::WriteStream *_out;
|
||||||
bool _stdin, _stdout, _stderr;
|
bool _stdin, _stdout, _stderr;
|
||||||
|
@ -52,6 +55,9 @@ public:
|
||||||
LuaFile();
|
LuaFile();
|
||||||
~LuaFile();
|
~LuaFile();
|
||||||
|
|
||||||
|
void saveState(SaveGame *state) const;
|
||||||
|
bool restoreState(SaveGame *state);
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
bool isOpen() const;
|
bool isOpen() const;
|
||||||
uint32 read(void *buf, uint32 len);
|
uint32 read(void *buf, uint32 len);
|
||||||
|
@ -190,23 +196,23 @@ lua_Object lua_setfallback(const char *event, lua_CFunction fallback);
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Copyright (c) 1994-1998 TeCGraf, PUC-Rio. All rights reserved.
|
* Copyright (c) 1994-1998 TeCGraf, PUC-Rio. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, without written agreement and without license
|
* Permission is hereby granted, without written agreement and without license
|
||||||
* or royalty fees, to use, copy, modify, and distribute this software and its
|
* or royalty fees, to use, copy, modify, and distribute this software and its
|
||||||
* documentation for any purpose, including commercial applications, subject to
|
* documentation for any purpose, including commercial applications, subject to
|
||||||
* the following conditions:
|
* the following conditions:
|
||||||
*
|
*
|
||||||
* - The above copyright notice and this permission notice shall appear in all
|
* - The above copyright notice and this permission notice shall appear in all
|
||||||
* copies or substantial portions of this software.
|
* copies or substantial portions of this software.
|
||||||
*
|
*
|
||||||
* - The origin of this software must not be misrepresented; you must not
|
* - The origin of this software must not be misrepresented; you must not
|
||||||
* claim that you wrote the original software. If you use this software in a
|
* claim that you wrote the original software. If you use this software in a
|
||||||
* product, an acknowledgment in the product documentation would be greatly
|
* product, an acknowledgment in the product documentation would be greatly
|
||||||
* appreciated (but it is not required).
|
* appreciated (but it is not required).
|
||||||
*
|
*
|
||||||
* - Altered source versions must be plainly marked as such, and must not be
|
* - Altered source versions must be plainly marked as such, and must not be
|
||||||
* misrepresented as being the original software.
|
* misrepresented as being the original software.
|
||||||
*
|
*
|
||||||
* The authors specifically disclaim any warranties, including, but not limited
|
* The authors specifically disclaim any warranties, including, but not limited
|
||||||
* to, the implied warranties of merchantability and fitness for a particular
|
* to, the implied warranties of merchantability and fitness for a particular
|
||||||
* purpose. The software provided hereunder is on an "as is" basis, and the
|
* purpose. The software provided hereunder is on an "as is" basis, and the
|
||||||
|
@ -215,7 +221,7 @@ lua_Object lua_setfallback(const char *event, lua_CFunction fallback);
|
||||||
* authors be held liable to any party for direct, indirect, special,
|
* authors be held liable to any party for direct, indirect, special,
|
||||||
* incidental, or consequential damages arising out of the use of this software
|
* incidental, or consequential damages arising out of the use of this software
|
||||||
* and its documentation.
|
* and its documentation.
|
||||||
*
|
*
|
||||||
* The Lua language and this implementation have been entirely designed and
|
* The Lua language and this implementation have been entirely designed and
|
||||||
* written by Waldemar Celes Filho, Roberto Ierusalimschy and
|
* written by Waldemar Celes Filho, Roberto Ierusalimschy and
|
||||||
* Luiz Henrique de Figueiredo at TeCGraf, PUC-Rio.
|
* Luiz Henrique de Figueiredo at TeCGraf, PUC-Rio.
|
||||||
|
|
|
@ -38,6 +38,9 @@
|
||||||
#include "engines/grim/lua/lauxlib.h"
|
#include "engines/grim/lua/lauxlib.h"
|
||||||
#include "engines/grim/imuse/imuse.h"
|
#include "engines/grim/imuse/imuse.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
extern Imuse *g_imuse;
|
extern Imuse *g_imuse;
|
||||||
|
@ -133,7 +136,7 @@ static void PrintWarning() {
|
||||||
static void FunctionName() {
|
static void FunctionName() {
|
||||||
const char *name;
|
const char *name;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
const char *filename;
|
const char *filename = 0;
|
||||||
int32 line;
|
int32 line;
|
||||||
lua_Object param1 = lua_getparam(1);
|
lua_Object param1 = lua_getparam(1);
|
||||||
|
|
||||||
|
@ -153,6 +156,7 @@ static void FunctionName() {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
// cout<<(void*)filename<<endl;
|
||||||
if (line == 0)
|
if (line == 0)
|
||||||
sprintf(buf, "main of %.100s", filename);
|
sprintf(buf, "main of %.100s", filename);
|
||||||
else if (line < 0)
|
else if (line < 0)
|
||||||
|
@ -724,13 +728,13 @@ static void GetActorYawToPoint() {
|
||||||
if (lua_istable(pointObj)) {
|
if (lua_istable(pointObj)) {
|
||||||
lua_pushobject(pointObj);
|
lua_pushobject(pointObj);
|
||||||
lua_pushstring("x");
|
lua_pushstring("x");
|
||||||
xObj = lua_gettable();
|
xObj = lua_gettable();
|
||||||
lua_pushobject(pointObj);
|
lua_pushobject(pointObj);
|
||||||
lua_pushstring("y");
|
lua_pushstring("y");
|
||||||
yObj = lua_gettable();
|
yObj = lua_gettable();
|
||||||
lua_pushobject(pointObj);
|
lua_pushobject(pointObj);
|
||||||
lua_pushstring("z");
|
lua_pushstring("z");
|
||||||
zObj = lua_gettable();
|
zObj = lua_gettable();
|
||||||
} else {
|
} else {
|
||||||
xObj = pointObj;
|
xObj = pointObj;
|
||||||
yObj = lua_getparam(3);
|
yObj = lua_getparam(3);
|
||||||
|
@ -1017,7 +1021,6 @@ static void SetActorColormap() {
|
||||||
Actor *actor = static_cast<Actor *>(lua_getuserdata(actorObj));
|
Actor *actor = static_cast<Actor *>(lua_getuserdata(actorObj));
|
||||||
if (lua_isstring(nameObj)) {
|
if (lua_isstring(nameObj)) {
|
||||||
const char *name = lua_getstring(nameObj);
|
const char *name = lua_getstring(nameObj);
|
||||||
g_resourceloader->loadColormap(name);
|
|
||||||
actor->setColormap(name);
|
actor->setColormap(name);
|
||||||
} else if (lua_isnil(nameObj)) {
|
} else if (lua_isnil(nameObj)) {
|
||||||
error("SetActorColormap: implement remove cmap");
|
error("SetActorColormap: implement remove cmap");
|
||||||
|
@ -1360,7 +1363,7 @@ static void ActorLookAt() {
|
||||||
fZ = 0.0f;
|
fZ = 0.0f;
|
||||||
|
|
||||||
Graphics::Vector3d vector;
|
Graphics::Vector3d vector;
|
||||||
vector.set(fX, fY, fZ);
|
vector.set(fX, fY, fZ); //FIXME: This values are wrong when looking at something manny has in his hand
|
||||||
actor->setLookAtVector(vector);
|
actor->setLookAtVector(vector);
|
||||||
} else if (lua_isuserdata(xObj) && lua_tag(xObj) == MKID_BE('ACTR')) { // look at another actor
|
} else if (lua_isuserdata(xObj) && lua_tag(xObj) == MKID_BE('ACTR')) { // look at another actor
|
||||||
Actor *lookedAct = static_cast<Actor *>(lua_getuserdata(xObj));
|
Actor *lookedAct = static_cast<Actor *>(lua_getuserdata(xObj));
|
||||||
|
@ -1408,7 +1411,7 @@ static void TurnActorTo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO turning stuff below is not complete
|
// TODO turning stuff below is not complete
|
||||||
|
|
||||||
// Find the vector pointing from the actor to the desired location
|
// Find the vector pointing from the actor to the desired location
|
||||||
Graphics::Vector3d turnToVector(x, y, z);
|
Graphics::Vector3d turnToVector(x, y, z);
|
||||||
Graphics::Vector3d lookVector = turnToVector - actor->pos();
|
Graphics::Vector3d lookVector = turnToVector - actor->pos();
|
||||||
|
@ -1447,7 +1450,7 @@ static void PointActorAt() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO turning stuff below is not complete
|
// TODO turning stuff below is not complete
|
||||||
|
|
||||||
// Find the vector pointing from the actor to the desired location
|
// Find the vector pointing from the actor to the desired location
|
||||||
Graphics::Vector3d turnToVector(x, y, z);
|
Graphics::Vector3d turnToVector(x, y, z);
|
||||||
Graphics::Vector3d lookVector = turnToVector - actor->pos();
|
Graphics::Vector3d lookVector = turnToVector - actor->pos();
|
||||||
|
@ -1715,12 +1718,13 @@ static void GetVisibleThings() {
|
||||||
|
|
||||||
// TODO verify code below
|
// TODO verify code below
|
||||||
for (GrimEngine::ActorListType::const_iterator i = g_grim->actorsBegin(); i != g_grim->actorsEnd(); ++i) {
|
for (GrimEngine::ActorListType::const_iterator i = g_grim->actorsBegin(); i != g_grim->actorsEnd(); ++i) {
|
||||||
if (!(*i)->inSet(g_grim->sceneName()))
|
Actor *a = i->_value;
|
||||||
|
if (!i->_value->inSet(g_grim->sceneName()))
|
||||||
continue;
|
continue;
|
||||||
// Consider the active actor visible
|
// Consider the active actor visible
|
||||||
if (actor == (*i) || actor->angleTo(*(*i)) < 90) {
|
if (actor == a || actor->angleTo(*a) < 90) {
|
||||||
lua_pushobject(result);
|
lua_pushobject(result);
|
||||||
lua_pushusertag(*i, MKID_BE('ACTR'));
|
lua_pushusertag(a, MKID_BE('ACTR'));
|
||||||
lua_pushnumber(1);
|
lua_pushnumber(1);
|
||||||
lua_settable();
|
lua_settable();
|
||||||
}
|
}
|
||||||
|
@ -2612,6 +2616,7 @@ static void FileFindDispose() {
|
||||||
if (g_filesiter)
|
if (g_filesiter)
|
||||||
g_filesiter->begin();
|
g_filesiter->begin();
|
||||||
g_listfiles.clear();
|
g_listfiles.clear();
|
||||||
|
g_filesiter = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void luaFileFindNext() {
|
static void luaFileFindNext() {
|
||||||
|
@ -2630,7 +2635,7 @@ static void luaFileFindFirst() {
|
||||||
lua_pushnil();
|
lua_pushnil();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileFindDispose();
|
FileFindDispose();
|
||||||
|
|
||||||
const char *extension = lua_getstring(extObj);
|
const char *extension = lua_getstring(extObj);
|
||||||
|
@ -2716,7 +2721,7 @@ void GetControlState() {
|
||||||
|
|
||||||
static void killBitmapPrimitives(Bitmap *bitmap) {
|
static void killBitmapPrimitives(Bitmap *bitmap) {
|
||||||
for (GrimEngine::PrimitiveListType::const_iterator i = g_grim->primitivesBegin(); i != g_grim->primitivesEnd(); ++i) {
|
for (GrimEngine::PrimitiveListType::const_iterator i = g_grim->primitivesBegin(); i != g_grim->primitivesEnd(); ++i) {
|
||||||
PrimitiveObject *p = *i;
|
PrimitiveObject *p = i->_value;
|
||||||
if (p->isBitmap() && p->getBitmapHandle() == bitmap) {
|
if (p->isBitmap() && p->getBitmapHandle() == bitmap) {
|
||||||
g_grim->killPrimitiveObject(p);
|
g_grim->killPrimitiveObject(p);
|
||||||
break;
|
break;
|
||||||
|
@ -2731,7 +2736,9 @@ static void GetImage() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const char *bitmapName = lua_getstring(nameObj);
|
const char *bitmapName = lua_getstring(nameObj);
|
||||||
Bitmap *image = g_resourceloader->loadBitmap(bitmapName);
|
BitmapPtr ptr = g_resourceloader->getBitmap(bitmapName).object();
|
||||||
|
Bitmap *image = ptr.object();
|
||||||
|
image->ref();
|
||||||
lua_pushusertag(image, MKID_BE('VBUF'));
|
lua_pushusertag(image, MKID_BE('VBUF'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2740,6 +2747,7 @@ static void FreeImage() {
|
||||||
if (!lua_isuserdata(param) || lua_tag(param) != MKID_BE('VBUF'))
|
if (!lua_isuserdata(param) || lua_tag(param) != MKID_BE('VBUF'))
|
||||||
return;
|
return;
|
||||||
Bitmap *bitmap = static_cast<Bitmap *>(lua_getuserdata(param));
|
Bitmap *bitmap = static_cast<Bitmap *>(lua_getuserdata(param));
|
||||||
|
bitmap->deref();
|
||||||
killBitmapPrimitives(bitmap);
|
killBitmapPrimitives(bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2988,11 +2996,11 @@ static void GetTextObjectDimensions() {
|
||||||
static void ExpireText() {
|
static void ExpireText() {
|
||||||
// Expire all the text objects
|
// Expire all the text objects
|
||||||
for (GrimEngine::TextListType::const_iterator i = g_grim->textsBegin(); i != g_grim->textsEnd(); ++i)
|
for (GrimEngine::TextListType::const_iterator i = g_grim->textsBegin(); i != g_grim->textsEnd(); ++i)
|
||||||
(*i)->setDisabled(true);
|
i->_value->setDisabled(true);
|
||||||
|
|
||||||
// Cleanup actor references to deleted text objects
|
// Cleanup actor references to deleted text objects
|
||||||
for (GrimEngine::ActorListType::const_iterator i = g_grim->actorsBegin(); i != g_grim->actorsEnd(); ++i)
|
for (GrimEngine::ActorListType::const_iterator i = g_grim->actorsBegin(); i != g_grim->actorsEnd(); ++i)
|
||||||
(*i)->lineCleanup();
|
i->_value->lineCleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetTextCharPosition() {
|
static void GetTextCharPosition() {
|
||||||
|
@ -3233,7 +3241,7 @@ static void ChangePrimitive() {
|
||||||
psearch = static_cast<PrimitiveObject *>(lua_getuserdata(param1));
|
psearch = static_cast<PrimitiveObject *>(lua_getuserdata(param1));
|
||||||
|
|
||||||
for (GrimEngine::PrimitiveListType::const_iterator i = g_grim->primitivesBegin(); i != g_grim->primitivesEnd(); ++i) {
|
for (GrimEngine::PrimitiveListType::const_iterator i = g_grim->primitivesBegin(); i != g_grim->primitivesEnd(); ++i) {
|
||||||
PrimitiveObject *p = *i;
|
PrimitiveObject *p = i->_value;
|
||||||
if (p->getP1().x == psearch->getP1().x && p->getP2().x == psearch->getP2().x
|
if (p->getP1().x == psearch->getP1().x && p->getP2().x == psearch->getP2().x
|
||||||
&& p->getP1().y == psearch->getP1().y && p->getP2().y == psearch->getP2().y) {
|
&& p->getP1().y == psearch->getP1().y && p->getP2().y == psearch->getP2().y) {
|
||||||
pmodify = p;
|
pmodify = p;
|
||||||
|
@ -3441,6 +3449,7 @@ static void NewObjectState() {
|
||||||
bool transparency = getbool(5);
|
bool transparency = getbool(5);
|
||||||
|
|
||||||
ObjectState *state = new ObjectState(setupID, pos, bitmap, zbitmap, transparency);
|
ObjectState *state = new ObjectState(setupID, pos, bitmap, zbitmap, transparency);
|
||||||
|
g_grim->registerObjectState(state);
|
||||||
g_grim->currScene()->addObjectState(state);
|
g_grim->currScene()->addObjectState(state);
|
||||||
lua_pushusertag(state, MKID_BE('STAT'));
|
lua_pushusertag(state, MKID_BE('STAT'));
|
||||||
}
|
}
|
||||||
|
@ -3451,6 +3460,7 @@ static void FreeObjectState() {
|
||||||
return;
|
return;
|
||||||
ObjectState *state = static_cast<ObjectState *>(lua_getuserdata(param));
|
ObjectState *state = static_cast<ObjectState *>(lua_getuserdata(param));
|
||||||
g_grim->currScene()->deleteObjectState(state);
|
g_grim->currScene()->deleteObjectState(state);
|
||||||
|
cout<<"free "<<state<<endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SendObjectToBack() {
|
static void SendObjectToBack() {
|
||||||
|
@ -3636,10 +3646,11 @@ static void LockFont() {
|
||||||
lua_Object param1 = lua_getparam(1);
|
lua_Object param1 = lua_getparam(1);
|
||||||
if (lua_isstring(param1)) {
|
if (lua_isstring(param1)) {
|
||||||
const char *fontName = lua_getstring(param1);
|
const char *fontName = lua_getstring(param1);
|
||||||
Font *result = g_resourceloader->loadFont(fontName);
|
FontPtr ptr = g_resourceloader->getFont(fontName);
|
||||||
|
Font *result = ptr.object();
|
||||||
|
result->ref();
|
||||||
if (result) {
|
if (result) {
|
||||||
lua_pushusertag(result, MKID_BE('FONT'));
|
lua_pushusertag(result, MKID_BE('FONT'));
|
||||||
g_grim->registerFont(result);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
Material::Material(const char *filename, const char *data, int len, const CMap *cmap) :
|
Material::Material(const char *filename, const char *data, int len, CMap *cmap) :
|
||||||
_fname(filename), _cmap(cmap) {
|
Object(), _fname(filename), _cmap(cmap) {
|
||||||
if (len < 4 || memcmp(data, "MAT ", 4) != 0)
|
if (len < 4 || memcmp(data, "MAT ", 4) != 0)
|
||||||
error("invalid magic loading texture");
|
error("invalid magic loading texture");
|
||||||
|
|
||||||
|
@ -59,6 +59,8 @@ void Material::select() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Material::~Material() {
|
Material::~Material() {
|
||||||
|
if (g_resourceloader)
|
||||||
|
g_resourceloader->uncacheMaterial(this);
|
||||||
if (_width == 0 || _height == 0)
|
if (_width == 0 || _height == 0)
|
||||||
return;
|
return;
|
||||||
g_driver->destroyMaterial(this);
|
g_driver->destroyMaterial(this);
|
||||||
|
|
|
@ -27,14 +27,17 @@
|
||||||
#define GRIM_MATERIAL_H
|
#define GRIM_MATERIAL_H
|
||||||
|
|
||||||
#include "engines/grim/resource.h"
|
#include "engines/grim/resource.h"
|
||||||
|
#include "engines/grim/object.h"
|
||||||
|
#include "engines/grim/colormap.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
class Material {
|
class Material : public Object {
|
||||||
|
GRIM_OBJECT(Material)
|
||||||
public:
|
public:
|
||||||
Material() {}
|
Material() { _width = 0; }
|
||||||
// Load a texture from the given data.
|
// Load a texture from the given data.
|
||||||
Material(const char *filename, const char *data, int len, const CMap *cmap);
|
Material(const char *filename, const char *data, int len, CMap *cmap);
|
||||||
|
|
||||||
// Load this texture into the GL context
|
// Load this texture into the GL context
|
||||||
void select() const;
|
void select() const;
|
||||||
|
@ -44,12 +47,13 @@ public:
|
||||||
|
|
||||||
int numImages() const { return _numImages; }
|
int numImages() const { return _numImages; }
|
||||||
int currentImage() const { return _currImage; }
|
int currentImage() const { return _currImage; }
|
||||||
|
const char *filename() { return _fname.c_str(); }
|
||||||
|
|
||||||
~Material();
|
~Material();
|
||||||
|
|
||||||
Common::String _fname;
|
Common::String _fname;
|
||||||
|
|
||||||
const CMap *_cmap;
|
const CMapPtr _cmap;
|
||||||
int _numImages, _currImage;
|
int _numImages, _currImage;
|
||||||
int _width, _height;
|
int _width, _height;
|
||||||
void *_textures;
|
void *_textures;
|
||||||
|
|
|
@ -34,9 +34,10 @@
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
Model::Model(const char *filename, const char *data, int len, const CMap *cmap) :
|
Model::Model(const char *filename, const char *data, int len, CMap *cmap) :
|
||||||
_numMaterials(0), _numGeosets(0) {
|
Object(), _numMaterials(0), _numGeosets(0), _cmap(cmap) {
|
||||||
_fname = filename;
|
_fname = filename;
|
||||||
|
_headNode = NULL;
|
||||||
|
|
||||||
if (len >= 4 && READ_BE_UINT32(data) == MKID_BE('LDOM'))
|
if (len >= 4 && READ_BE_UINT32(data) == MKID_BE('LDOM'))
|
||||||
loadBinary(data, cmap);
|
loadBinary(data, cmap);
|
||||||
|
@ -46,35 +47,50 @@ Model::Model(const char *filename, const char *data, int len, const CMap *cmap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::reload(const CMap *cmap) {
|
void Model::reload(CMap *cmap) {
|
||||||
// Load the new colormap
|
// Load the new colormap
|
||||||
for (int i = 0; i < _numMaterials; i++)
|
for (int i = 0; i < _numMaterials; i++) {
|
||||||
_materials[i] = g_resourceloader->loadMaterial(_materialNames[i], cmap);
|
_materials[i] = g_resourceloader->getMaterial(_materialNames[i], cmap);
|
||||||
|
}
|
||||||
|
Material **materials = new Material*[_numMaterials];
|
||||||
|
for (int j = 0; j < _numMaterials; ++j) {
|
||||||
|
materials[j] = _materials[j];
|
||||||
|
}
|
||||||
for (int i = 0; i < _numGeosets; i++)
|
for (int i = 0; i < _numGeosets; i++)
|
||||||
_geosets[i].changeMaterials(_materials);
|
_geosets[i].changeMaterials(materials);
|
||||||
|
delete[] materials;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::loadBinary(const char *&data, const CMap *cmap) {
|
void Model::loadBinary(const char *&data, CMap *cmap) {
|
||||||
_numMaterials = READ_LE_UINT32(data + 4);
|
_numMaterials = READ_LE_UINT32(data + 4);
|
||||||
data += 8;
|
data += 8;
|
||||||
_materials = new Material*[_numMaterials];
|
_materials = new MaterialPtr[_numMaterials];
|
||||||
_materialNames = new char[_numMaterials][32];
|
_materialNames = new char[_numMaterials][32];
|
||||||
for (int i = 0; i < _numMaterials; i++) {
|
for (int i = 0; i < _numMaterials; i++) {
|
||||||
strcpy(_materialNames[i], data);
|
strcpy(_materialNames[i], data);
|
||||||
_materials[i] = g_resourceloader->loadMaterial(_materialNames[i], cmap);
|
_materials[i] = g_resourceloader->getMaterial(_materialNames[i], cmap);
|
||||||
data += 32;
|
data += 32;
|
||||||
}
|
}
|
||||||
data += 32; // skip name
|
data += 32; // skip name
|
||||||
_numGeosets = READ_LE_UINT32(data + 4);
|
_numGeosets = READ_LE_UINT32(data + 4);
|
||||||
data += 8;
|
data += 8;
|
||||||
_geosets = new Geoset[_numGeosets];
|
_geosets = new Geoset[_numGeosets];
|
||||||
|
Material **materials = new Material*[_numMaterials];
|
||||||
|
for (int j = 0; j < _numMaterials; ++j) {
|
||||||
|
materials[j] = _materials[j];
|
||||||
|
}
|
||||||
for (int i = 0; i < _numGeosets; i++)
|
for (int i = 0; i < _numGeosets; i++)
|
||||||
_geosets[i].loadBinary(data, _materials);
|
_geosets[i].loadBinary(data, materials);
|
||||||
|
delete[] materials;
|
||||||
_numHierNodes = READ_LE_UINT32(data + 4);
|
_numHierNodes = READ_LE_UINT32(data + 4);
|
||||||
data += 8;
|
data += 8;
|
||||||
_rootHierNode = new HierNode[_numHierNodes];
|
_rootHierNode = new HierNode[_numHierNodes];
|
||||||
for (int i = 0; i < _numHierNodes; i++)
|
for (int i = 0; i < _numHierNodes; i++) {
|
||||||
_rootHierNode[i].loadBinary(data, _rootHierNode, &_geosets[0]);
|
_rootHierNode[i].loadBinary(data, _rootHierNode, &_geosets[0]);
|
||||||
|
if (strcmp(_rootHierNode[i]._name, "head") == 0) {
|
||||||
|
_headNode = _rootHierNode + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
_radius = get_float(data);
|
_radius = get_float(data);
|
||||||
_insertOffset = Graphics::get_vector3d(data + 40);
|
_insertOffset = Graphics::get_vector3d(data + 40);
|
||||||
}
|
}
|
||||||
|
@ -84,6 +100,7 @@ Model::~Model() {
|
||||||
delete[] _materialNames;
|
delete[] _materialNames;
|
||||||
delete[] _geosets;
|
delete[] _geosets;
|
||||||
delete[] _rootHierNode;
|
delete[] _rootHierNode;
|
||||||
|
g_resourceloader->uncacheModel(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::Geoset::loadBinary(const char *&data, Material *materials[]) {
|
void Model::Geoset::loadBinary(const char *&data, Material *materials[]) {
|
||||||
|
@ -144,6 +161,7 @@ Model::Mesh::~Mesh() {
|
||||||
delete[] _vertNormals;
|
delete[] _vertNormals;
|
||||||
delete[] _textureVerts;
|
delete[] _textureVerts;
|
||||||
delete[] _faces;
|
delete[] _faces;
|
||||||
|
delete[] _materialid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::Mesh::update() {
|
void Model::Mesh::update() {
|
||||||
|
@ -262,20 +280,20 @@ Model::HierNode *Model::copyHierarchy() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::loadText(TextSplitter *ts, const CMap *cmap) {
|
void Model::loadText(TextSplitter *ts, CMap *cmap) {
|
||||||
ts->expectString("section: header");
|
ts->expectString("section: header");
|
||||||
int major, minor;
|
int major, minor;
|
||||||
ts->scanString("3do %d.%d", 2, &major, &minor);
|
ts->scanString("3do %d.%d", 2, &major, &minor);
|
||||||
ts->expectString("section: modelresource");
|
ts->expectString("section: modelresource");
|
||||||
ts->scanString("materials %d", 1, &_numMaterials);
|
ts->scanString("materials %d", 1, &_numMaterials);
|
||||||
_materials = new Material*[_numMaterials];
|
_materials = new MaterialPtr[_numMaterials];
|
||||||
_materialNames = new char[_numMaterials][32];
|
_materialNames = new char[_numMaterials][32];
|
||||||
for (int i = 0; i < _numMaterials; i++) {
|
for (int i = 0; i < _numMaterials; i++) {
|
||||||
char materialName[32];
|
char materialName[32];
|
||||||
int num;
|
int num;
|
||||||
|
|
||||||
ts->scanString("%d: %32s", 2, &num, materialName);
|
ts->scanString("%d: %32s", 2, &num, materialName);
|
||||||
_materials[num] = g_resourceloader->loadMaterial(materialName, cmap);
|
_materials[num] = g_resourceloader->getMaterial(materialName, cmap);
|
||||||
strcpy(_materialNames[num], materialName);
|
strcpy(_materialNames[num], materialName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,11 +302,16 @@ void Model::loadText(TextSplitter *ts, const CMap *cmap) {
|
||||||
ts->scanString("insert offset %f %f %f", 3, &_insertOffset.x(), &_insertOffset.y(), &_insertOffset.z());
|
ts->scanString("insert offset %f %f %f", 3, &_insertOffset.x(), &_insertOffset.y(), &_insertOffset.z());
|
||||||
ts->scanString("geosets %d", 1, &_numGeosets);
|
ts->scanString("geosets %d", 1, &_numGeosets);
|
||||||
_geosets = new Geoset[_numGeosets];
|
_geosets = new Geoset[_numGeosets];
|
||||||
|
Material **materials = new Material*[_numMaterials];
|
||||||
|
for (int j = 0; j < _numMaterials; ++j) {
|
||||||
|
materials[j] = _materials[j];
|
||||||
|
}
|
||||||
for (int i = 0; i < _numGeosets; i++) {
|
for (int i = 0; i < _numGeosets; i++) {
|
||||||
int num;
|
int num;
|
||||||
ts->scanString("geoset %d", 1, &num);
|
ts->scanString("geoset %d", 1, &num);
|
||||||
_geosets[num].loadText(ts, _materials);
|
_geosets[num].loadText(ts, materials);
|
||||||
}
|
}
|
||||||
|
delete[] materials;
|
||||||
|
|
||||||
ts->expectString("section: hierarchydef");
|
ts->expectString("section: hierarchydef");
|
||||||
ts->scanString("hierarchy nodes %d", 1, &_numHierNodes);
|
ts->scanString("hierarchy nodes %d", 1, &_numHierNodes);
|
||||||
|
@ -358,7 +381,7 @@ void Model::Mesh::changeMaterials(Material *materials[]) {
|
||||||
_faces[i].changeMaterial(materials[_materialid[i]]);
|
_faces[i].changeMaterial(materials[_materialid[i]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::Mesh::loadText(TextSplitter *ts, Material *materials[]) {
|
void Model::Mesh::loadText(TextSplitter *ts, Material* materials[]) {
|
||||||
ts->scanString("name %32s", 1, _name);
|
ts->scanString("name %32s", 1, _name);
|
||||||
ts->scanString("radius %f", 1, &_radius);
|
ts->scanString("radius %f", 1, &_radius);
|
||||||
|
|
||||||
|
|
|
@ -27,24 +27,27 @@
|
||||||
#define GRIM_MODEL_H
|
#define GRIM_MODEL_H
|
||||||
|
|
||||||
#include "engines/grim/resource.h"
|
#include "engines/grim/resource.h"
|
||||||
|
#include "engines/grim/object.h"
|
||||||
#include "graphics/matrix4.h"
|
#include "graphics/matrix4.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
class TextSplitter;
|
class TextSplitter;
|
||||||
|
|
||||||
class Model {
|
class Model : public Object {
|
||||||
|
GRIM_OBJECT(Model)
|
||||||
public:
|
public:
|
||||||
// Construct a 3D model from the given data.
|
// Construct a 3D model from the given data.
|
||||||
Model(const char *filename, const char *data, int len, const CMap *cmap);
|
Model(const char *filename, const char *data, int len, CMap *cmap);
|
||||||
void loadBinary(const char *&data, const CMap *cmap);
|
void loadBinary(const char *&data, CMap *cmap);
|
||||||
void loadText(TextSplitter *ts, const CMap *cmap);
|
void loadText(TextSplitter *ts, CMap *cmap);
|
||||||
void reload(const CMap *cmap);
|
void reload(CMap *cmap);
|
||||||
void draw() const;
|
void draw() const;
|
||||||
|
|
||||||
~Model();
|
~Model();
|
||||||
|
|
||||||
Common::String _fname;
|
Common::String _fname;
|
||||||
|
CMapPtr _cmap;
|
||||||
|
|
||||||
struct Geoset;
|
struct Geoset;
|
||||||
struct Mesh;
|
struct Mesh;
|
||||||
|
@ -132,13 +135,14 @@ public:
|
||||||
|
|
||||||
int _numMaterials;
|
int _numMaterials;
|
||||||
char (*_materialNames)[32];
|
char (*_materialNames)[32];
|
||||||
Material **_materials;
|
MaterialPtr *_materials;
|
||||||
Graphics::Vector3d _insertOffset;
|
Graphics::Vector3d _insertOffset;
|
||||||
int _numGeosets;
|
int _numGeosets;
|
||||||
Geoset *_geosets;
|
Geoset *_geosets;
|
||||||
float _radius;
|
float _radius;
|
||||||
int _numHierNodes;
|
int _numHierNodes;
|
||||||
HierNode *_rootHierNode;
|
HierNode *_rootHierNode;
|
||||||
|
HierNode *_headNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -59,6 +59,7 @@ MODULE_OBJS := \
|
||||||
scene.o \
|
scene.o \
|
||||||
textobject.o \
|
textobject.o \
|
||||||
textsplit.o \
|
textsplit.o \
|
||||||
|
object.o \
|
||||||
walkplane.o
|
walkplane.o
|
||||||
|
|
||||||
# This module can be built as a plugin
|
# This module can be built as a plugin
|
||||||
|
|
96
engines/grim/object.cpp
Normal file
96
engines/grim/object.cpp
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
|
||||||
|
#include "object.h"
|
||||||
|
#include "engines/grim/savegame.h"
|
||||||
|
|
||||||
|
#include "engines/grim/lua/lobject.h"
|
||||||
|
|
||||||
|
namespace Grim {
|
||||||
|
|
||||||
|
typedef Object *(*CreatorFunc)();
|
||||||
|
Common::HashMap<Common::String, CreatorFunc> ObjectManager::_creators;
|
||||||
|
|
||||||
|
Object::Object() : _refCount(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Object::~Object() {
|
||||||
|
luaO_resetObject(this); //after climbing the ties rope an ObjectState gets deleted but not removed
|
||||||
|
//from the lua's userdata list, resulting in a dangling pointer
|
||||||
|
//that breaks the saving. We need to reset to NULL the pointer manually.
|
||||||
|
for (Common::List<Pointer *>::iterator i = _pointers.begin(); i != _pointers.end(); ++i) {
|
||||||
|
(*i)->resetPointer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::save(SaveGame *state) const {
|
||||||
|
state->writeLEUint32(_refCount);
|
||||||
|
|
||||||
|
saveState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Object::restore(SaveGame *state) {
|
||||||
|
_refCount = state->readLEUint32();
|
||||||
|
|
||||||
|
return restoreState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::saveState(SaveGame */*state*/) const {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Object::restoreState(SaveGame */*state*/) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::ref() {
|
||||||
|
++_refCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::deref() {
|
||||||
|
if (_refCount > 0) {
|
||||||
|
--_refCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_refCount == 0) {
|
||||||
|
_refCount = -1;
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ObjectManager::saveObject(SaveGame *state, Object *object) {
|
||||||
|
const char *str = object->typeName();
|
||||||
|
int32 len = strlen(str);
|
||||||
|
|
||||||
|
state->writeLEUint32(len);
|
||||||
|
state->write(str, len);
|
||||||
|
|
||||||
|
object->save(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object *ObjectManager::restoreObject(SaveGame *state) {
|
||||||
|
int32 len = state->readLEUint32();
|
||||||
|
char *str = new char[len + 1];
|
||||||
|
state->read(str, len);
|
||||||
|
str[len] = '\0';
|
||||||
|
|
||||||
|
Object *o = newObject(str);
|
||||||
|
delete[] str;
|
||||||
|
o->restore(state);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object *ObjectManager::newObject(const char *typeName) {
|
||||||
|
Common::String type = typeName;
|
||||||
|
if (_creators.contains(type)) {
|
||||||
|
CreatorFunc func = _creators.getVal(type);
|
||||||
|
Object *o = (func)();
|
||||||
|
return o;
|
||||||
|
} else {
|
||||||
|
warning("Type name \"%s\" not registered", typeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
212
engines/grim/object.h
Normal file
212
engines/grim/object.h
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
/* Residual - A 3D game interpreter
|
||||||
|
*
|
||||||
|
* Residual is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the AUTHORS
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRIM_OBJECT_H
|
||||||
|
#define GRIM_OBJECT_H
|
||||||
|
|
||||||
|
#include "common/str.h"
|
||||||
|
#include "common/hashmap.h"
|
||||||
|
#include "common/hash-str.h"
|
||||||
|
#include "common/func.h"
|
||||||
|
#include "common/list.h"
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
namespace Grim {
|
||||||
|
|
||||||
|
class SaveGame;
|
||||||
|
|
||||||
|
class Pointer;
|
||||||
|
class Object {
|
||||||
|
public:
|
||||||
|
Object();
|
||||||
|
virtual ~Object();
|
||||||
|
|
||||||
|
virtual const char *typeName() const { return ""; }
|
||||||
|
|
||||||
|
void save(SaveGame *state) const;
|
||||||
|
bool restore(SaveGame *state);
|
||||||
|
|
||||||
|
void ref();
|
||||||
|
void deref();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void saveState(SaveGame *state) const;
|
||||||
|
virtual bool restoreState(SaveGame *state);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _refCount;
|
||||||
|
Common::List<Pointer *> _pointers;
|
||||||
|
|
||||||
|
friend class Pointer;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Pointer {
|
||||||
|
protected:
|
||||||
|
virtual ~Pointer() {}
|
||||||
|
|
||||||
|
void addPointer(Object *obj) {
|
||||||
|
obj->_pointers.push_back(this);
|
||||||
|
}
|
||||||
|
void rmPointer(Object *obj) {
|
||||||
|
obj->_pointers.remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void resetPointer() {}
|
||||||
|
|
||||||
|
friend class Object;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> class ObjectPtr : public Pointer {
|
||||||
|
public:
|
||||||
|
ObjectPtr() :
|
||||||
|
_obj(NULL) {
|
||||||
|
|
||||||
|
}
|
||||||
|
ObjectPtr(T *obj) :
|
||||||
|
_obj(obj) {
|
||||||
|
if (obj) {
|
||||||
|
_obj->ref();
|
||||||
|
addPointer(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ObjectPtr(const ObjectPtr<T> &ptr) {
|
||||||
|
_obj = NULL;
|
||||||
|
*this = ptr;
|
||||||
|
}
|
||||||
|
~ObjectPtr() {
|
||||||
|
if (_obj) {
|
||||||
|
rmPointer(_obj);
|
||||||
|
_obj->deref();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectPtr &operator=(T *obj) {
|
||||||
|
if (obj != _obj) {
|
||||||
|
if (_obj) {
|
||||||
|
rmPointer(_obj);
|
||||||
|
_obj->deref();
|
||||||
|
_obj = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj) {
|
||||||
|
_obj = obj;
|
||||||
|
_obj->ref();
|
||||||
|
addPointer(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
ObjectPtr &operator=(const ObjectPtr<T> &ptr) {
|
||||||
|
if (_obj != ptr._obj) {
|
||||||
|
if (_obj) {
|
||||||
|
rmPointer(_obj);
|
||||||
|
_obj->deref();
|
||||||
|
_obj = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr._obj) {
|
||||||
|
_obj = ptr._obj;
|
||||||
|
_obj->ref();
|
||||||
|
addPointer(_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
bool operator==(const ObjectPtr &ptr) const {
|
||||||
|
return (_obj == ptr._obj);
|
||||||
|
}
|
||||||
|
bool operator==(Object *obj) const {
|
||||||
|
return (_obj == obj);
|
||||||
|
}
|
||||||
|
operator bool() const {
|
||||||
|
return (_obj);
|
||||||
|
}
|
||||||
|
bool operator!() const {
|
||||||
|
return (!_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
T *object() const {
|
||||||
|
return _obj;
|
||||||
|
}
|
||||||
|
T *operator->() const {
|
||||||
|
return _obj;
|
||||||
|
}
|
||||||
|
T &operator*() const {
|
||||||
|
return *_obj;
|
||||||
|
}
|
||||||
|
operator T*() const {
|
||||||
|
return _obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resetPointer() {
|
||||||
|
_obj = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T *_obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ObjectManager {
|
||||||
|
public:
|
||||||
|
static void saveObject(SaveGame *state, Object *object);
|
||||||
|
static Object *restoreObject(SaveGame *state);
|
||||||
|
static Object *newObject(const char *typeName);
|
||||||
|
|
||||||
|
template<class T> static bool registerType() {
|
||||||
|
T obj;
|
||||||
|
Common::String type = obj.typeName();
|
||||||
|
if (_creators.contains(type)) {
|
||||||
|
warning("Type name %s already registered", type.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_creators.setVal(type, &createObj<T>);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<class T> static Object *createObj() {
|
||||||
|
return new T();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef Object *(*CreatorFunc)();
|
||||||
|
static Common::HashMap<Common::String, CreatorFunc> _creators;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace Grim
|
||||||
|
|
||||||
|
#define GRIM_OBJECT(class) \
|
||||||
|
public: \
|
||||||
|
const char *typeName() const { \
|
||||||
|
return #class; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -26,37 +26,80 @@
|
||||||
#include "engines/grim/objectstate.h"
|
#include "engines/grim/objectstate.h"
|
||||||
#include "engines/grim/savegame.h"
|
#include "engines/grim/savegame.h"
|
||||||
#include "engines/grim/lua.h"
|
#include "engines/grim/lua.h"
|
||||||
|
#include "engines/grim/grim.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
int ObjectState::s_id = 0;
|
||||||
|
|
||||||
ObjectState::ObjectState(int setup, ObjectState::Position position, const char *bitmap, const char *zbitmap, bool transparency) :
|
ObjectState::ObjectState(int setup, ObjectState::Position position, const char *bitmap, const char *zbitmap, bool transparency) :
|
||||||
_setupID(setup), _pos(position), _visibility(false) {
|
Object(), _setupID(setup), _pos(position), _visibility(false) {
|
||||||
_bitmap = g_resourceloader->loadBitmap(bitmap);
|
_bitmap = g_resourceloader->getBitmap(bitmap);
|
||||||
if (zbitmap)
|
if (zbitmap) {
|
||||||
_zbitmap = g_resourceloader->loadBitmap(zbitmap);
|
_zbitmap = g_resourceloader->getBitmap(zbitmap);
|
||||||
else
|
} else
|
||||||
_zbitmap = NULL;
|
_zbitmap = NULL;
|
||||||
|
|
||||||
|
++s_id;
|
||||||
|
_id = s_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectState::ObjectState() :
|
||||||
|
Object(), _bitmap(NULL), _zbitmap(NULL) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectState::~ObjectState() {
|
ObjectState::~ObjectState() {
|
||||||
|
g_grim->killObjectState(this);
|
||||||
// g_resourceloader->uncache(_bitmap->getFilename());
|
// g_resourceloader->uncache(_bitmap->getFilename());
|
||||||
// if (_zbitmap)
|
// if (_zbitmap)
|
||||||
// g_resourceloader->uncache(_zbitmap->getFilename());
|
// g_resourceloader->uncache(_zbitmap->getFilename());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectState::saveState(SaveGame *savedState) {
|
void ObjectState::saveState(SaveGame *savedState) const {
|
||||||
PointerId ptr;
|
|
||||||
|
|
||||||
savedState->writeLESint32(_visibility);
|
savedState->writeLESint32(_visibility);
|
||||||
savedState->writeLEUint32(_setupID);
|
savedState->writeLEUint32(_setupID);
|
||||||
savedState->writeLEUint32(_pos);
|
savedState->writeLEUint32(_pos);
|
||||||
|
|
||||||
ptr = makeIdFromPointer(_bitmap);
|
//_bitmap
|
||||||
savedState->writeLEUint32(ptr.low);
|
if (_bitmap) {
|
||||||
savedState->writeLEUint32(ptr.hi);
|
savedState->writeLEUint32(1);
|
||||||
ptr = makeIdFromPointer(_zbitmap);
|
savedState->writeCharString(_bitmap->filename());
|
||||||
savedState->writeLEUint32(ptr.low);
|
} else {
|
||||||
savedState->writeLEUint32(ptr.hi);
|
savedState->writeLEUint32(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//_zbitmap
|
||||||
|
if (_zbitmap) {
|
||||||
|
savedState->writeLEUint32(1);
|
||||||
|
savedState->writeCharString(_zbitmap->filename());
|
||||||
|
} else {
|
||||||
|
savedState->writeLEUint32(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectState::restoreState(SaveGame *savedState) {
|
||||||
|
_visibility = savedState->readLEUint32();
|
||||||
|
_setupID = savedState->readLEUint32();
|
||||||
|
_pos = (Position) savedState->readLEUint32();
|
||||||
|
|
||||||
|
if (savedState->readLEUint32()) {
|
||||||
|
const char *name = savedState->readCharString();
|
||||||
|
_bitmap = g_resourceloader->getBitmap(name);
|
||||||
|
delete[] name;
|
||||||
|
} else {
|
||||||
|
_bitmap = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (savedState->readLEUint32()) {
|
||||||
|
const char *name = savedState->readCharString();
|
||||||
|
_zbitmap = g_resourceloader->getBitmap(name);
|
||||||
|
delete[] name;
|
||||||
|
} else {
|
||||||
|
_zbitmap = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -27,12 +27,14 @@
|
||||||
#define GRIM_OSTATE_H
|
#define GRIM_OSTATE_H
|
||||||
|
|
||||||
#include "engines/grim/bitmap.h"
|
#include "engines/grim/bitmap.h"
|
||||||
|
#include "engines/grim/object.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
class SaveGame;
|
class SaveGame;
|
||||||
|
|
||||||
class ObjectState {
|
class ObjectState : public Object {
|
||||||
|
GRIM_OBJECT(ObjectState)
|
||||||
public:
|
public:
|
||||||
enum Position {
|
enum Position {
|
||||||
OBJSTATE_BACKGROUND = 0,
|
OBJSTATE_BACKGROUND = 0,
|
||||||
|
@ -42,9 +44,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
ObjectState(int setupID, ObjectState::Position pos, const char *bitmap, const char *zbitmap, bool visible);
|
ObjectState(int setupID, ObjectState::Position pos, const char *bitmap, const char *zbitmap, bool visible);
|
||||||
|
ObjectState();
|
||||||
~ObjectState();
|
~ObjectState();
|
||||||
|
|
||||||
void saveState(SaveGame *savedState);
|
void saveState(SaveGame *savedState) const;
|
||||||
|
bool restoreState(SaveGame *savedState);
|
||||||
|
|
||||||
int setupID() const { return _setupID; }
|
int setupID() const { return _setupID; }
|
||||||
Position pos() const { return _pos; }
|
Position pos() const { return _pos; }
|
||||||
|
@ -78,7 +82,12 @@ private:
|
||||||
bool _visibility;
|
bool _visibility;
|
||||||
int _setupID;
|
int _setupID;
|
||||||
Position _pos;
|
Position _pos;
|
||||||
Bitmap *_bitmap, *_zbitmap;
|
BitmapPtr _bitmap, _zbitmap;
|
||||||
|
|
||||||
|
int _id;
|
||||||
|
static int s_id;
|
||||||
|
|
||||||
|
friend class GrimEngine;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -30,29 +30,32 @@
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
PrimitiveObject::PrimitiveObject() {
|
int PrimitiveObject::s_id = 0;
|
||||||
memset(&_color, 0, sizeof(Color));
|
|
||||||
|
PrimitiveObject::PrimitiveObject() :
|
||||||
|
Object() {
|
||||||
|
// memset(&_color, 0, sizeof(Color));
|
||||||
_filled = false;
|
_filled = false;
|
||||||
_type = 0;
|
_type = 0;
|
||||||
_bitmap = NULL;
|
_bitmap = NULL;
|
||||||
|
++s_id;
|
||||||
|
_id = s_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrimitiveObject::~PrimitiveObject() {
|
PrimitiveObject::~PrimitiveObject() {
|
||||||
if (_type == 2)
|
if (_bitmap && _type == 2)
|
||||||
g_driver->destroyBitmap(_bitmap);
|
g_driver->destroyBitmap(_bitmap.object());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrimitiveObject::saveState(SaveGame *savedState) {
|
void PrimitiveObject::saveState(SaveGame *savedState) const {
|
||||||
PointerId ptr;
|
|
||||||
|
|
||||||
savedState->writeLESint32(_type);
|
savedState->writeLESint32(_type);
|
||||||
savedState->writeLEUint32(_color.red());
|
|
||||||
savedState->writeLEUint32(_color.green());
|
savedState->writeColor(_color);
|
||||||
savedState->writeLEUint32(_color.blue());
|
|
||||||
savedState->writeLEUint32(_filled);
|
savedState->writeLEUint32(_filled);
|
||||||
ptr = makeIdFromPointer(_bitmap);
|
|
||||||
savedState->writeLEUint32(ptr.low);
|
savedState->writeCharString(_bitmap->filename());
|
||||||
savedState->writeLEUint32(ptr.hi);
|
|
||||||
savedState->writeLEUint32(_p1.x);
|
savedState->writeLEUint32(_p1.x);
|
||||||
savedState->writeLEUint32(_p1.y);
|
savedState->writeLEUint32(_p1.y);
|
||||||
savedState->writeLEUint32(_p2.x);
|
savedState->writeLEUint32(_p2.x);
|
||||||
|
@ -63,6 +66,29 @@ void PrimitiveObject::saveState(SaveGame *savedState) {
|
||||||
savedState->writeLEUint32(_p4.y);
|
savedState->writeLEUint32(_p4.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PrimitiveObject::restoreState(SaveGame *savedState) {
|
||||||
|
_type = savedState->readLESint32();
|
||||||
|
|
||||||
|
_color = savedState->readColor();
|
||||||
|
|
||||||
|
_filled = savedState->readLEUint32();
|
||||||
|
|
||||||
|
const char *name = savedState->readCharString();
|
||||||
|
_bitmap = g_resourceloader->getBitmap(name);
|
||||||
|
delete[] name;
|
||||||
|
|
||||||
|
_p1.x = savedState->readLEUint32();
|
||||||
|
_p1.y = savedState->readLEUint32();
|
||||||
|
_p2.x = savedState->readLEUint32();
|
||||||
|
_p2.y = savedState->readLEUint32();
|
||||||
|
_p3.x = savedState->readLEUint32();
|
||||||
|
_p3.y = savedState->readLEUint32();
|
||||||
|
_p4.x = savedState->readLEUint32();
|
||||||
|
_p4.y = savedState->readLEUint32();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void PrimitiveObject::createRectangle(Common::Point p1, Common::Point p2, Color color, bool filled) {
|
void PrimitiveObject::createRectangle(Common::Point p1, Common::Point p2, Color color, bool filled) {
|
||||||
_type = RECTANGLE;
|
_type = RECTANGLE;
|
||||||
_p1 = p1;
|
_p1 = p1;
|
||||||
|
@ -77,7 +103,7 @@ void PrimitiveObject::createBitmap(Bitmap *bitmap, Common::Point p, bool /*trans
|
||||||
_bitmap->setX(p.x);
|
_bitmap->setX(p.x);
|
||||||
_bitmap->setY(p.y);
|
_bitmap->setY(p.y);
|
||||||
// transparent: what to do ?
|
// transparent: what to do ?
|
||||||
g_driver->createBitmap(_bitmap);
|
g_driver->createBitmap(bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrimitiveObject::createLine(Common::Point p1, Common::Point p2, Color color) {
|
void PrimitiveObject::createLine(Common::Point p1, Common::Point p2, Color color) {
|
||||||
|
@ -102,7 +128,7 @@ void PrimitiveObject::draw() {
|
||||||
if (_type == RECTANGLE)
|
if (_type == RECTANGLE)
|
||||||
g_driver->drawRectangle(this);
|
g_driver->drawRectangle(this);
|
||||||
else if (_type == BITMAP)
|
else if (_type == BITMAP)
|
||||||
g_driver->drawBitmap(_bitmap);
|
g_driver->drawBitmap(_bitmap.object());
|
||||||
else if (_type == LINE)
|
else if (_type == LINE)
|
||||||
g_driver->drawLine(this);
|
g_driver->drawLine(this);
|
||||||
else if (_type == POLYGON)
|
else if (_type == POLYGON)
|
||||||
|
|
|
@ -34,7 +34,8 @@ namespace Grim {
|
||||||
|
|
||||||
class SaveGame;
|
class SaveGame;
|
||||||
|
|
||||||
class PrimitiveObject {
|
class PrimitiveObject : public Object {
|
||||||
|
GRIM_OBJECT(PrimitiveObject)
|
||||||
public:
|
public:
|
||||||
PrimitiveObject();
|
PrimitiveObject();
|
||||||
~PrimitiveObject();
|
~PrimitiveObject();
|
||||||
|
@ -60,15 +61,21 @@ public:
|
||||||
bool isFilled() { return _filled; }
|
bool isFilled() { return _filled; }
|
||||||
void draw();
|
void draw();
|
||||||
bool isBitmap() { return _type == BITMAP; }
|
bool isBitmap() { return _type == BITMAP; }
|
||||||
Bitmap *getBitmapHandle() { assert(_bitmap); return _bitmap; }
|
Bitmap *getBitmapHandle() { assert(_bitmap); return _bitmap.object(); }
|
||||||
void saveState(SaveGame *savedState);
|
void saveState(SaveGame *state) const;
|
||||||
|
bool restoreState(SaveGame *state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Common::Point _p1, _p2, _p3, _p4;
|
Common::Point _p1, _p2, _p3, _p4;
|
||||||
Color _color;
|
Color _color;
|
||||||
bool _filled;
|
bool _filled;
|
||||||
int _type;
|
int _type;
|
||||||
Bitmap *_bitmap;
|
BitmapPtr _bitmap;
|
||||||
|
|
||||||
|
int _id;
|
||||||
|
static int s_id;
|
||||||
|
|
||||||
|
friend class GrimEngine;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
#include "engines/grim/material.h"
|
#include "engines/grim/material.h"
|
||||||
#include "engines/grim/grim.h"
|
#include "engines/grim/grim.h"
|
||||||
#include "engines/grim/lipsync.h"
|
#include "engines/grim/lipsync.h"
|
||||||
|
#include "engines/grim/savegame.h"
|
||||||
|
#include "engines/grim/actor.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
@ -108,7 +111,7 @@ Block *ResourceLoader::getFileFromCache(const char *filename) {
|
||||||
ResourceLoader::ResourceCache *ResourceLoader::getEntryFromCache(const char *filename) {
|
ResourceLoader::ResourceCache *ResourceLoader::getEntryFromCache(const char *filename) {
|
||||||
if (_cache.empty())
|
if (_cache.empty())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (_cacheDirty) {
|
if (_cacheDirty) {
|
||||||
qsort(_cache.begin(), _cache.size(), sizeof(ResourceCache), sortCallback);
|
qsort(_cache.begin(), _cache.size(), sizeof(ResourceCache), sortCallback);
|
||||||
_cacheDirty = false;
|
_cacheDirty = false;
|
||||||
|
@ -132,6 +135,20 @@ Block *ResourceLoader::getFileBlock(const char *filename) const {
|
||||||
return l->getFileBlock(filename);
|
return l->getFileBlock(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Block *ResourceLoader::getBlock(const char *filename) {
|
||||||
|
Common::String fname = filename;
|
||||||
|
fname.toLowercase();
|
||||||
|
Block *b = getFileFromCache(fname.c_str());
|
||||||
|
if (!b) {
|
||||||
|
b = getFileBlock(fname.c_str());
|
||||||
|
if (b) {
|
||||||
|
putIntoCache(fname, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
LuaFile *ResourceLoader::openNewStreamLuaFile(const char *filename) const {
|
LuaFile *ResourceLoader::openNewStreamLuaFile(const char *filename) const {
|
||||||
const Lab *l = getLab(filename);
|
const Lab *l = getLab(filename);
|
||||||
|
|
||||||
|
@ -182,6 +199,7 @@ Bitmap *ResourceLoader::loadBitmap(const char *filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap *result = g_grim->registerBitmap(filename, b->data(), b->len());
|
Bitmap *result = g_grim->registerBitmap(filename, b->data(), b->len());
|
||||||
|
_bitmaps.push_back(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -192,12 +210,14 @@ CMap *ResourceLoader::loadColormap(const char *filename) {
|
||||||
Block *b = getFileFromCache(fname.c_str());
|
Block *b = getFileFromCache(fname.c_str());
|
||||||
if (!b) {
|
if (!b) {
|
||||||
b = getFileBlock(fname.c_str());
|
b = getFileBlock(fname.c_str());
|
||||||
if (!b)
|
if (!b) {
|
||||||
error("Could not find colormap %s", filename);
|
error("Could not find colormap %s", filename);
|
||||||
|
}
|
||||||
putIntoCache(fname, b);
|
putIntoCache(fname, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMap *result = new CMap(filename, b->data(), b->len());
|
CMap *result = new CMap(filename, b->data(), b->len());
|
||||||
|
_colormaps.push_back(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -209,10 +229,11 @@ Costume *ResourceLoader::loadCostume(const char *filename, Costume *prevCost) {
|
||||||
if (!b) {
|
if (!b) {
|
||||||
b = getFileBlock(fname.c_str());
|
b = getFileBlock(fname.c_str());
|
||||||
if (!b)
|
if (!b)
|
||||||
error("Could not find costume %s", filename);
|
error("Could not find costume \"%s\"", filename);
|
||||||
putIntoCache(fname, b);
|
putIntoCache(fname, b);
|
||||||
}
|
}
|
||||||
Costume *result = new Costume(filename, b->data(), b->len(), prevCost);
|
Costume *result = new Costume(filename, b->data(), b->len(), prevCost);
|
||||||
|
_costumes.push_back(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -229,6 +250,7 @@ Font *ResourceLoader::loadFont(const char *filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Font *result = new Font(filename, b->data(), b->len());
|
Font *result = new Font(filename, b->data(), b->len());
|
||||||
|
_fonts.push_back(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -245,6 +267,7 @@ KeyframeAnim *ResourceLoader::loadKeyframe(const char *filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyframeAnim *result = new KeyframeAnim(filename, b->data(), b->len());
|
KeyframeAnim *result = new KeyframeAnim(filename, b->data(), b->len());
|
||||||
|
_keyframeAnims.push_back(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -265,6 +288,7 @@ LipSync *ResourceLoader::loadLipSync(const char *filename) {
|
||||||
// Some lipsync files have no data
|
// Some lipsync files have no data
|
||||||
if (result->isValid()) {
|
if (result->isValid()) {
|
||||||
putIntoCache(fname, b);
|
putIntoCache(fname, b);
|
||||||
|
_lipsyncs.push_back(result);
|
||||||
} else {
|
} else {
|
||||||
delete result;
|
delete result;
|
||||||
delete b;
|
delete b;
|
||||||
|
@ -274,7 +298,7 @@ LipSync *ResourceLoader::loadLipSync(const char *filename) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Material *ResourceLoader::loadMaterial(const char *filename, const CMap *c) {
|
Material *ResourceLoader::loadMaterial(const char *filename, CMap *c) {
|
||||||
Common::String fname = Common::String(filename);
|
Common::String fname = Common::String(filename);
|
||||||
fname.toLowercase();
|
fname.toLowercase();
|
||||||
Block *b = getFileFromCache(fname.c_str());
|
Block *b = getFileFromCache(fname.c_str());
|
||||||
|
@ -286,11 +310,12 @@ Material *ResourceLoader::loadMaterial(const char *filename, const CMap *c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Material *result = new Material(fname.c_str(), b->data(), b->len(), c);
|
Material *result = new Material(fname.c_str(), b->data(), b->len(), c);
|
||||||
|
_materials.push_back(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Model *ResourceLoader::loadModel(const char *filename, const CMap *c) {
|
Model *ResourceLoader::loadModel(const char *filename, CMap *c) {
|
||||||
Common::String fname = filename;
|
Common::String fname = filename;
|
||||||
fname.toLowercase();
|
fname.toLowercase();
|
||||||
Block *b = getFileFromCache(fname.c_str());
|
Block *b = getFileFromCache(fname.c_str());
|
||||||
|
@ -302,6 +327,7 @@ Model *ResourceLoader::loadModel(const char *filename, const CMap *c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Model *result = new Model(filename, b->data(), b->len(), c);
|
Model *result = new Model(filename, b->data(), b->len(), c);
|
||||||
|
_models.push_back(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -326,4 +352,124 @@ void ResourceLoader::uncache(const char *filename) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourceLoader::uncacheMaterial(Material *mat) {
|
||||||
|
_materials.remove(mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceLoader::uncacheBitmap(Bitmap *bitmap) {
|
||||||
|
_bitmaps.remove(bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceLoader::uncacheModel(Model *m) {
|
||||||
|
_models.remove(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceLoader::uncacheColormap(CMap *c) {
|
||||||
|
_colormaps.remove(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceLoader::uncacheKeyframe(KeyframeAnim *k) {
|
||||||
|
_keyframeAnims.remove(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceLoader::uncacheFont(Font *f) {
|
||||||
|
_fonts.remove(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceLoader::uncacheCostume(Costume *c) {
|
||||||
|
_costumes.remove(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceLoader::uncacheLipSync(LipSync *s) {
|
||||||
|
_lipsyncs.remove(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialPtr ResourceLoader::getMaterial(const char *fname, CMap *c) {
|
||||||
|
for (Common::List<Material *>::const_iterator i = _materials.begin(); i != _materials.end(); ++i) {
|
||||||
|
Material *m = *i;
|
||||||
|
if (strcmp(fname, m->_fname.c_str()) == 0 && *m->_cmap == *c) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadMaterial(fname, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
BitmapPtr ResourceLoader::getBitmap(const char *fname) {
|
||||||
|
for (Common::List<Bitmap *>::const_iterator i = _bitmaps.begin(); i != _bitmaps.end(); ++i) {
|
||||||
|
Bitmap *b = *i;
|
||||||
|
if (strcmp(fname, b->filename()) == 0) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadBitmap(fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelPtr ResourceLoader::getModel(const char *fname, CMap *c) {
|
||||||
|
for (Common::List<Model *>::const_iterator i = _models.begin(); i != _models.end(); ++i) {
|
||||||
|
Model *m = *i;
|
||||||
|
if (strcmp(fname, m->_fname.c_str()) == 0 && *m->_cmap == *c) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadModel(fname, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMapPtr ResourceLoader::getColormap(const char *fname) {
|
||||||
|
for (Common::List<CMap *>::const_iterator i = _colormaps.begin(); i != _colormaps.end(); ++i) {
|
||||||
|
CMap *c = *i;
|
||||||
|
if (strcmp(fname, c->_fname.c_str()) == 0) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadColormap(fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyframeAnimPtr ResourceLoader::getKeyframe(const char *fname) {
|
||||||
|
for (Common::List<KeyframeAnim *>::const_iterator i = _keyframeAnims.begin(); i != _keyframeAnims.end(); ++i) {
|
||||||
|
KeyframeAnim *k = *i;
|
||||||
|
if (strcmp(fname, k->filename()) == 0) {
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadKeyframe(fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
FontPtr ResourceLoader::getFont(const char *fname) {
|
||||||
|
for (Common::List<Font *>::const_iterator i = _fonts.begin(); i != _fonts.end(); ++i) {
|
||||||
|
Font *f = *i;
|
||||||
|
if (strcmp(fname, f->getFilename().c_str()) == 0) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadFont(fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
CostumePtr ResourceLoader::getCostume(const char *fname, Costume *prev) {
|
||||||
|
for (Common::List<Costume *>::const_iterator i = _costumes.begin(); i != _costumes.end(); ++i) {
|
||||||
|
Costume *c = *i;
|
||||||
|
if (strcmp(fname, c->filename()) == 0) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadCostume(fname, prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
LipSyncPtr ResourceLoader::getLipSync(const char *fname) {
|
||||||
|
for (Common::List<LipSync *>::const_iterator i = _lipsyncs.begin(); i != _lipsyncs.end(); ++i) {
|
||||||
|
LipSync *l = *i;
|
||||||
|
if (strcmp(fname, l->filename()) == 0) {
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadLipSync(fname);
|
||||||
|
}
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "common/archive.h"
|
#include "common/archive.h"
|
||||||
|
|
||||||
#include "engines/grim/lab.h"
|
#include "engines/grim/lab.h"
|
||||||
|
#include "engines/grim/object.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
@ -40,6 +41,17 @@ class KeyframeAnim;
|
||||||
class Material;
|
class Material;
|
||||||
class Model;
|
class Model;
|
||||||
class LipSync;
|
class LipSync;
|
||||||
|
class TrackedObject;
|
||||||
|
class SaveGame;
|
||||||
|
|
||||||
|
typedef ObjectPtr<Material> MaterialPtr;
|
||||||
|
typedef ObjectPtr<Bitmap> BitmapPtr;
|
||||||
|
typedef ObjectPtr<Model> ModelPtr;
|
||||||
|
typedef ObjectPtr<CMap> CMapPtr;
|
||||||
|
typedef ObjectPtr<KeyframeAnim> KeyframeAnimPtr;
|
||||||
|
typedef ObjectPtr<Font> FontPtr;
|
||||||
|
typedef ObjectPtr<Costume> CostumePtr;
|
||||||
|
typedef ObjectPtr<LipSync> LipSyncPtr;
|
||||||
|
|
||||||
class ResourceLoader {
|
class ResourceLoader {
|
||||||
public:
|
public:
|
||||||
|
@ -51,23 +63,40 @@ public:
|
||||||
Costume *loadCostume(const char *fname, Costume *prevCost);
|
Costume *loadCostume(const char *fname, Costume *prevCost);
|
||||||
Font *loadFont(const char *fname);
|
Font *loadFont(const char *fname);
|
||||||
KeyframeAnim *loadKeyframe(const char *fname);
|
KeyframeAnim *loadKeyframe(const char *fname);
|
||||||
Material *loadMaterial(const char *fname, const CMap *c);
|
Material *loadMaterial(const char *fname, CMap *c);
|
||||||
Model *loadModel(const char *fname, const CMap *c);
|
Model *loadModel(const char *fname, CMap *c);
|
||||||
LipSync *loadLipSync(const char *fname);
|
LipSync *loadLipSync(const char *fname);
|
||||||
Block *getFileBlock(const char *filename) const;
|
Block *getFileBlock(const char *filename) const;
|
||||||
|
Block *getBlock(const char *filename);
|
||||||
Common::File *openNewStreamFile(const char *filename) const;
|
Common::File *openNewStreamFile(const char *filename) const;
|
||||||
LuaFile *openNewStreamLuaFile(const char *filename) const;
|
LuaFile *openNewStreamLuaFile(const char *filename) const;
|
||||||
void uncache(const char *fname);
|
void uncache(const char *fname);
|
||||||
bool fileExists(const char *filename) const;
|
bool fileExists(const char *filename) const;
|
||||||
int fileLength(const char *filename) const;
|
int fileLength(const char *filename) const;
|
||||||
|
|
||||||
|
MaterialPtr getMaterial(const char *filename, CMap *c);
|
||||||
|
BitmapPtr getBitmap(const char *fname);
|
||||||
|
ModelPtr getModel(const char *fname, CMap *c);
|
||||||
|
CMapPtr getColormap(const char *fname);
|
||||||
|
KeyframeAnimPtr getKeyframe(const char *fname);
|
||||||
|
FontPtr getFont(const char *fname);
|
||||||
|
CostumePtr getCostume(const char *fname, Costume *prevCostume);
|
||||||
|
LipSyncPtr getLipSync(const char *fname);
|
||||||
|
void uncacheMaterial(Material *m);
|
||||||
|
void uncacheBitmap(Bitmap *bitmap);
|
||||||
|
void uncacheModel(Model *m);
|
||||||
|
void uncacheColormap(CMap *c);
|
||||||
|
void uncacheKeyframe(KeyframeAnim *kf);
|
||||||
|
void uncacheFont(Font *f);
|
||||||
|
void uncacheCostume(Costume *c);
|
||||||
|
void uncacheLipSync(LipSync *l);
|
||||||
|
|
||||||
struct ResourceCache {
|
struct ResourceCache {
|
||||||
char *fname;
|
char *fname;
|
||||||
Block *resPtr;
|
Block *resPtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const Lab *getLab(const char *filename) const;
|
const Lab *getLab(const char *filename) const;
|
||||||
Block *getFileFromCache(const char *filename);
|
Block *getFileFromCache(const char *filename);
|
||||||
ResourceLoader::ResourceCache *getEntryFromCache(const char *filename);
|
ResourceLoader::ResourceCache *getEntryFromCache(const char *filename);
|
||||||
|
@ -80,6 +109,15 @@ private:
|
||||||
Common::Array<ResourceCache> _cache;
|
Common::Array<ResourceCache> _cache;
|
||||||
bool _cacheDirty;
|
bool _cacheDirty;
|
||||||
int32 _cacheMemorySize;
|
int32 _cacheMemorySize;
|
||||||
|
|
||||||
|
Common::List<Material *> _materials;
|
||||||
|
Common::List<Bitmap *> _bitmaps;
|
||||||
|
Common::List<Model *> _models;
|
||||||
|
Common::List<CMap *> _colormaps;
|
||||||
|
Common::List<KeyframeAnim *> _keyframeAnims;
|
||||||
|
Common::List<Font *> _fonts;
|
||||||
|
Common::List<Costume *> _costumes;
|
||||||
|
Common::List<LipSync *> _lipsyncs;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ResourceLoader *g_resourceloader;
|
extern ResourceLoader *g_resourceloader;
|
||||||
|
|
|
@ -26,7 +26,10 @@
|
||||||
#include "common/endian.h"
|
#include "common/endian.h"
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
|
|
||||||
|
#include "graphics/vector3d.h"
|
||||||
|
|
||||||
#include "engines/grim/savegame.h"
|
#include "engines/grim/savegame.h"
|
||||||
|
#include "engines/grim/color.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
@ -228,4 +231,68 @@ void SaveGame::writeByte(byte data) {
|
||||||
_sectionSize++;
|
_sectionSize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SaveGame::writeVector3d(const Graphics::Vector3d &vec) {
|
||||||
|
writeFloat(vec.x());
|
||||||
|
writeFloat(vec.y());
|
||||||
|
writeFloat(vec.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveGame::writeColor(const Grim::Color &color) {
|
||||||
|
writeByte(color.red());
|
||||||
|
writeByte(color.green());
|
||||||
|
writeByte(color.blue());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveGame::writeFloat(float data) {
|
||||||
|
write(reinterpret_cast<void *>(&data), sizeof(float));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveGame::writeCharString(const char *string) {
|
||||||
|
int32 len = strlen(string);
|
||||||
|
writeLESint32(len);
|
||||||
|
write(string, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveGame::writeString(const Common::String &string) {
|
||||||
|
writeCharString(string.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics::Vector3d SaveGame::readVector3d() {
|
||||||
|
float x = readFloat();
|
||||||
|
float y = readFloat();
|
||||||
|
float z = readFloat();
|
||||||
|
return Graphics::Vector3d(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
Grim::Color SaveGame::readColor() {
|
||||||
|
Color color;
|
||||||
|
color.red() = readByte();
|
||||||
|
color.green() = readByte();
|
||||||
|
color.blue() = readByte();
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SaveGame::readFloat() {
|
||||||
|
float f;
|
||||||
|
read(reinterpret_cast<void *>(&f), sizeof(float));
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SaveGame::readCharString() {
|
||||||
|
int32 len = readLESint32();
|
||||||
|
char *str = new char[len + 1];
|
||||||
|
read(str, len);
|
||||||
|
str[len] = '\0';
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::String SaveGame::readString() {
|
||||||
|
const char *str = readCharString();
|
||||||
|
Common::String s = str;
|
||||||
|
delete[] str;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -28,8 +28,14 @@
|
||||||
|
|
||||||
#include "common/savefile.h"
|
#include "common/savefile.h"
|
||||||
|
|
||||||
|
namespace Graphics {
|
||||||
|
class Vector3d;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
class Color;
|
||||||
|
|
||||||
class SaveGame {
|
class SaveGame {
|
||||||
public:
|
public:
|
||||||
SaveGame(const char *filename, bool saving);
|
SaveGame(const char *filename, bool saving);
|
||||||
|
@ -48,6 +54,17 @@ public:
|
||||||
void writeLESint32(int32 data);
|
void writeLESint32(int32 data);
|
||||||
void writeLEBool(bool data);
|
void writeLEBool(bool data);
|
||||||
void writeByte(byte data);
|
void writeByte(byte data);
|
||||||
|
void writeCharString(const char *string);
|
||||||
|
void writeString(const Common::String &string);
|
||||||
|
|
||||||
|
void writeVector3d(const Graphics::Vector3d &vec);
|
||||||
|
void writeColor(const Grim::Color &color);
|
||||||
|
void writeFloat(float data);
|
||||||
|
Graphics::Vector3d readVector3d();
|
||||||
|
Grim::Color readColor();
|
||||||
|
float readFloat();
|
||||||
|
const char *readCharString();
|
||||||
|
Common::String readString();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool _saving;
|
bool _saving;
|
||||||
|
|
|
@ -28,11 +28,14 @@
|
||||||
#include "engines/grim/colormap.h"
|
#include "engines/grim/colormap.h"
|
||||||
#include "engines/grim/grim.h"
|
#include "engines/grim/grim.h"
|
||||||
#include "engines/grim/savegame.h"
|
#include "engines/grim/savegame.h"
|
||||||
|
#include "engines/grim/lua.h"
|
||||||
|
|
||||||
#include "engines/grim/imuse/imuse.h"
|
#include "engines/grim/imuse/imuse.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
int Scene::s_id = 0;
|
||||||
|
|
||||||
Scene::Scene(const char *sceneName, const char *buf, int len) :
|
Scene::Scene(const char *sceneName, const char *buf, int len) :
|
||||||
_locked(false), _name(sceneName), _enableLights(false) {
|
_locked(false), _name(sceneName), _enableLights(false) {
|
||||||
TextSplitter ts(buf, len);
|
TextSplitter ts(buf, len);
|
||||||
|
@ -40,15 +43,15 @@ Scene::Scene(const char *sceneName, const char *buf, int len) :
|
||||||
|
|
||||||
ts.expectString("section: colormaps");
|
ts.expectString("section: colormaps");
|
||||||
ts.scanString(" numcolormaps %d", 1, &_numCmaps);
|
ts.scanString(" numcolormaps %d", 1, &_numCmaps);
|
||||||
_cmaps = new CMap*[_numCmaps];
|
_cmaps = new CMapPtr[_numCmaps];
|
||||||
char cmap_name[256];
|
char cmap_name[256];
|
||||||
for (int i = 0; i < _numCmaps; i++) {
|
for (int i = 0; i < _numCmaps; i++) {
|
||||||
ts.scanString(" colormap %256s", 1, cmap_name);
|
ts.scanString(" colormap %256s", 1, cmap_name);
|
||||||
_cmaps[i] = g_resourceloader->loadColormap(cmap_name);
|
_cmaps[i] = g_resourceloader->getColormap(cmap_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ts.checkString("section: objectstates")) {
|
if (ts.checkString("section: object_states")) {
|
||||||
ts.expectString("section: objectstates");
|
ts.expectString("section: object_states");
|
||||||
ts.scanString(" tot_objects %d", 1, &_numObjectStates);
|
ts.scanString(" tot_objects %d", 1, &_numObjectStates);
|
||||||
char object_name[256];
|
char object_name[256];
|
||||||
for (int l = 0; l < _numObjectStates; l++) {
|
for (int l = 0; l < _numObjectStates; l++) {
|
||||||
|
@ -99,34 +102,199 @@ Scene::Scene(const char *sceneName, const char *buf, int len) :
|
||||||
_numSectors++;
|
_numSectors++;
|
||||||
}
|
}
|
||||||
// Allocate and fill an array of sector info
|
// Allocate and fill an array of sector info
|
||||||
_sectors = new Sector[_numSectors];
|
_sectors = new Sector*[_numSectors];
|
||||||
ts.setLineNumber(sectorStart);
|
ts.setLineNumber(sectorStart);
|
||||||
for (int i = 0; i < _numSectors; i++)
|
for (int i = 0; i < _numSectors; i++) {
|
||||||
_sectors[i].load(ts);
|
_sectors[i] = new Sector();
|
||||||
|
_sectors[i]->load(ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
++s_id;
|
||||||
|
_id = s_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene::Scene() :
|
||||||
|
_cmaps(NULL) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::~Scene() {
|
Scene::~Scene() {
|
||||||
delete[] _cmaps;
|
if (_cmaps) {
|
||||||
delete[] _setups;
|
delete[] _cmaps;
|
||||||
delete[] _lights;
|
delete[] _setups;
|
||||||
delete[] _sectors;
|
delete[] _lights;
|
||||||
for (StateList::iterator i = _states.begin(); i != _states.end(); ++i)
|
for (int i = 0; i < _numSectors; ++i) {
|
||||||
delete (*i);
|
delete _sectors[i];
|
||||||
|
}
|
||||||
|
delete[] _sectors;
|
||||||
|
for (StateList::iterator i = _states.begin(); i != _states.end(); ++i)
|
||||||
|
delete (*i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::saveState(SaveGame *savedState) {
|
void Scene::saveState(SaveGame *savedState) const {
|
||||||
savedState->writeLESint32(_name.size());
|
savedState->writeString(_name);
|
||||||
savedState->write(_name.c_str(), _name.size());
|
savedState->writeLESint32(_numCmaps);
|
||||||
|
for (int i = 0; i < _numCmaps; ++i) {
|
||||||
|
savedState->writeCharString(_cmaps[i]->filename());
|
||||||
|
}
|
||||||
savedState->writeLEUint32(_currSetup - _setups); // current setup id
|
savedState->writeLEUint32(_currSetup - _setups); // current setup id
|
||||||
savedState->writeLEUint32(_locked);
|
savedState->writeLEUint32(_locked);
|
||||||
savedState->writeLEUint32(_enableLights);
|
savedState->writeLEUint32(_enableLights);
|
||||||
savedState->writeLEUint32(_minVolume);
|
savedState->writeLEUint32(_minVolume);
|
||||||
savedState->writeLEUint32(_maxVolume);
|
savedState->writeLEUint32(_maxVolume);
|
||||||
|
|
||||||
savedState->writeLEUint32(_numObjectStates);
|
savedState->writeLEUint32(_states.size());
|
||||||
for (StateList::iterator i = _states.begin(); i != _states.end(); ++i) {
|
for (StateList::const_iterator i = _states.begin(); i != _states.end(); ++i) {
|
||||||
// ObjectState *s = *i;
|
savedState->writeLEUint32(g_grim->objectStateId(*i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Setups
|
||||||
|
savedState->writeLEUint32(_numSetups);
|
||||||
|
for (int i = 0; i < _numSetups; ++i) {
|
||||||
|
Setup &set = _setups[i];
|
||||||
|
|
||||||
|
//name
|
||||||
|
savedState->writeString(set._name);
|
||||||
|
|
||||||
|
//bkgndBm
|
||||||
|
if (set._bkgndBm) {
|
||||||
|
savedState->writeLEUint32(1);
|
||||||
|
savedState->writeCharString(set._bkgndBm->filename());
|
||||||
|
} else {
|
||||||
|
savedState->writeLEUint32(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//bkgndZBm
|
||||||
|
if (set._bkgndZBm) {
|
||||||
|
savedState->writeLEUint32(1);
|
||||||
|
savedState->writeCharString(set._bkgndZBm->filename());
|
||||||
|
} else {
|
||||||
|
savedState->writeLEUint32(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
savedState->writeVector3d(set._pos);
|
||||||
|
savedState->writeVector3d(set._interest);
|
||||||
|
savedState->writeFloat(set._roll);
|
||||||
|
savedState->writeFloat(set._fov);
|
||||||
|
savedState->writeFloat(set._nclip);
|
||||||
|
savedState->writeFloat(set._fclip);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sectors
|
||||||
|
savedState->writeLEUint32(_numSectors);
|
||||||
|
for (int i = 0; i < _numSectors; ++i) {
|
||||||
|
_sectors[i]->saveState(savedState);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Lights
|
||||||
|
savedState->writeLEUint32(_numLights);
|
||||||
|
for (int i = 0; i < _numLights; ++i) {
|
||||||
|
Light &l = _lights[i];
|
||||||
|
|
||||||
|
//name
|
||||||
|
savedState->writeString(l._name);
|
||||||
|
|
||||||
|
//type
|
||||||
|
savedState->writeString(l._type);
|
||||||
|
|
||||||
|
savedState->writeVector3d(l._pos);
|
||||||
|
savedState->writeVector3d(l._dir);
|
||||||
|
|
||||||
|
savedState->writeColor(l._color);
|
||||||
|
|
||||||
|
savedState->writeFloat(l._intensity);
|
||||||
|
savedState->writeFloat(l._umbraangle);
|
||||||
|
savedState->writeFloat(l._penumbraangle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scene::restoreState(SaveGame *savedState) {
|
||||||
|
_name = savedState->readString();
|
||||||
|
_numCmaps = savedState->readLESint32();
|
||||||
|
_cmaps = new CMapPtr[_numCmaps];
|
||||||
|
for (int i = 0; i < _numCmaps; ++i) {
|
||||||
|
const char *str = savedState->readCharString();
|
||||||
|
_cmaps[i] = g_resourceloader->getColormap(str);
|
||||||
|
delete[] str;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 currSetupId = savedState->readLEUint32();
|
||||||
|
_locked = savedState->readLEUint32();
|
||||||
|
_enableLights = savedState->readLEUint32();
|
||||||
|
_minVolume = savedState->readLEUint32();
|
||||||
|
_maxVolume = savedState->readLEUint32();
|
||||||
|
|
||||||
|
_numObjectStates = savedState->readLEUint32();
|
||||||
|
_states.clear();
|
||||||
|
for (int i = 0; i < _numObjectStates; ++i) {
|
||||||
|
int32 id = savedState->readLEUint32();
|
||||||
|
ObjectState *o = g_grim->objectState(id);
|
||||||
|
_states.push_back(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setups
|
||||||
|
_numSetups = savedState->readLEUint32();
|
||||||
|
_setups = new Setup[_numSetups];
|
||||||
|
_currSetup = _setups + currSetupId;
|
||||||
|
for (int i = 0; i < _numSetups; ++i) {
|
||||||
|
Setup &set = _setups[i];
|
||||||
|
|
||||||
|
set._name = savedState->readString();
|
||||||
|
|
||||||
|
if (savedState->readLEUint32()) {
|
||||||
|
const char *fname = savedState->readCharString();
|
||||||
|
set._bkgndBm = g_resourceloader->getBitmap(fname);
|
||||||
|
} else {
|
||||||
|
set._bkgndBm = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (savedState->readLEUint32()) {
|
||||||
|
const char *fname = savedState->readCharString();
|
||||||
|
set._bkgndZBm = g_resourceloader->getBitmap(fname);
|
||||||
|
} else {
|
||||||
|
set._bkgndZBm = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
set._pos = savedState->readVector3d();
|
||||||
|
set._interest = savedState->readVector3d();
|
||||||
|
set._roll = savedState->readFloat();
|
||||||
|
set._fov = savedState->readFloat();
|
||||||
|
set._nclip = savedState->readFloat();
|
||||||
|
set._fclip = savedState->readFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sectors
|
||||||
|
_numSectors = savedState->readLEUint32();
|
||||||
|
if (_numSectors > 0) {
|
||||||
|
_sectors = new Sector*[_numSectors];
|
||||||
|
for (int i = 0; i < _numSectors; ++i) {
|
||||||
|
_sectors[i] = new Sector();
|
||||||
|
_sectors[i]->restoreState(savedState);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_sectors = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
_numLights = savedState->readLEUint32();
|
||||||
|
_lights = new Light[_numLights];
|
||||||
|
for (int i = 0; i < _numLights; ++i) {
|
||||||
|
Light &l = _lights[i];
|
||||||
|
|
||||||
|
l._name = savedState->readString();
|
||||||
|
l._type = savedState->readString();
|
||||||
|
|
||||||
|
l._pos = savedState->readVector3d();
|
||||||
|
l._dir = savedState->readVector3d();
|
||||||
|
|
||||||
|
l._color = savedState->readColor();
|
||||||
|
|
||||||
|
l._intensity = savedState->readFloat();
|
||||||
|
l._umbraangle = savedState->readFloat();
|
||||||
|
l._penumbraangle = savedState->readFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::Setup::load(TextSplitter &ts) {
|
void Scene::Setup::load(TextSplitter &ts) {
|
||||||
|
@ -136,7 +304,7 @@ void Scene::Setup::load(TextSplitter &ts) {
|
||||||
_name = buf;
|
_name = buf;
|
||||||
|
|
||||||
ts.scanString(" background %256s", 1, buf);
|
ts.scanString(" background %256s", 1, buf);
|
||||||
_bkgndBm = g_resourceloader->loadBitmap(buf);
|
_bkgndBm = g_resourceloader->getBitmap(buf);
|
||||||
if (!_bkgndBm) {
|
if (!_bkgndBm) {
|
||||||
if (gDebugLevel == DEBUG_BITMAPS || gDebugLevel == DEBUG_ERROR || gDebugLevel == DEBUG_ALL)
|
if (gDebugLevel == DEBUG_BITMAPS || gDebugLevel == DEBUG_ERROR || gDebugLevel == DEBUG_ALL)
|
||||||
printf("Unable to load scene bitmap: %s\n", buf);
|
printf("Unable to load scene bitmap: %s\n", buf);
|
||||||
|
@ -152,7 +320,7 @@ void Scene::Setup::load(TextSplitter &ts) {
|
||||||
ts.scanString(" zbuffer %256s", 1, buf);
|
ts.scanString(" zbuffer %256s", 1, buf);
|
||||||
// Don't even try to load if it's the "none" bitmap
|
// Don't even try to load if it's the "none" bitmap
|
||||||
if (strcmp(buf, "<none>.lbm") != 0) {
|
if (strcmp(buf, "<none>.lbm") != 0) {
|
||||||
_bkgndZBm = g_resourceloader->loadBitmap(buf);
|
_bkgndZBm = g_resourceloader->getBitmap(buf);
|
||||||
if (gDebugLevel == DEBUG_BITMAPS || gDebugLevel == DEBUG_NORMAL || gDebugLevel == DEBUG_ALL)
|
if (gDebugLevel == DEBUG_BITMAPS || gDebugLevel == DEBUG_NORMAL || gDebugLevel == DEBUG_ALL)
|
||||||
printf("Loading scene z-buffer bitmap: %s\n", buf);
|
printf("Loading scene z-buffer bitmap: %s\n", buf);
|
||||||
}
|
}
|
||||||
|
@ -237,6 +405,19 @@ void Scene::setSetup(int num) {
|
||||||
g_grim->flagRefreshShadowMask(true);
|
g_grim->flagRefreshShadowMask(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scene::drawBackground() const {
|
||||||
|
if (_currSetup->_bkgndZBm) // Some screens have no zbuffer mask (eg, Alley)
|
||||||
|
_currSetup->_bkgndZBm->draw();
|
||||||
|
|
||||||
|
if (!_currSetup->_bkgndBm) {
|
||||||
|
// This should fail softly, for some reason jumping to the signpost (sg) will load
|
||||||
|
// the scene in such a way that the background isn't immediately available
|
||||||
|
warning("Background hasn't loaded yet for setup %s in %s!", _currSetup->_name.c_str(), _name.c_str());
|
||||||
|
} else {
|
||||||
|
_currSetup->_bkgndBm->draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Scene::drawBitmaps(ObjectState::Position stage) {
|
void Scene::drawBitmaps(ObjectState::Position stage) {
|
||||||
for (StateList::iterator i = _states.begin(); i != _states.end(); ++i) {
|
for (StateList::iterator i = _states.begin(); i != _states.end(); ++i) {
|
||||||
if ((*i)->pos() == stage && _currSetup == _setups + (*i)->setupID())
|
if ((*i)->pos() == stage && _currSetup == _setups + (*i)->setupID())
|
||||||
|
@ -246,8 +427,8 @@ void Scene::drawBitmaps(ObjectState::Position stage) {
|
||||||
|
|
||||||
Sector *Scene::findPointSector(Graphics::Vector3d p, int flags) {
|
Sector *Scene::findPointSector(Graphics::Vector3d p, int flags) {
|
||||||
for (int i = 0; i < _numSectors; i++) {
|
for (int i = 0; i < _numSectors; i++) {
|
||||||
Sector *sector = _sectors + i;
|
Sector *sector = _sectors[i];
|
||||||
if ((sector->type() & flags) && sector->visible() && sector->isPointInSector(p))
|
if (sector && (sector->type() & flags) && sector->visible() && sector->isPointInSector(p))
|
||||||
return sector;
|
return sector;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -259,7 +440,7 @@ void Scene::findClosestSector(Graphics::Vector3d p, Sector **sect, Graphics::Vec
|
||||||
float minDist = 0.0;
|
float minDist = 0.0;
|
||||||
|
|
||||||
for (int i = 0; i < _numSectors; i++) {
|
for (int i = 0; i < _numSectors; i++) {
|
||||||
Sector *sector = _sectors + i;
|
Sector *sector = _sectors[i];
|
||||||
if ((sector->type() & 0x1000) == 0 || !sector->visible())
|
if ((sector->type() & 0x1000) == 0 || !sector->visible())
|
||||||
continue;
|
continue;
|
||||||
Graphics::Vector3d closestPt = sector->closestPoint(p);
|
Graphics::Vector3d closestPt = sector->closestPoint(p);
|
||||||
|
|
|
@ -37,25 +37,16 @@ class SaveGame;
|
||||||
class Scene {
|
class Scene {
|
||||||
public:
|
public:
|
||||||
Scene(const char *name, const char *buf, int len);
|
Scene(const char *name, const char *buf, int len);
|
||||||
|
Scene();
|
||||||
~Scene();
|
~Scene();
|
||||||
|
|
||||||
void saveState(SaveGame *savedState);
|
void saveState(SaveGame *savedState) const;
|
||||||
|
bool restoreState(SaveGame *savedState);
|
||||||
|
|
||||||
int _minVolume;
|
int _minVolume;
|
||||||
int _maxVolume;
|
int _maxVolume;
|
||||||
|
|
||||||
void drawBackground() const {
|
void drawBackground() const;
|
||||||
if (_currSetup->_bkgndZBm) // Some screens have no zbuffer mask (eg, Alley)
|
|
||||||
_currSetup->_bkgndZBm->draw();
|
|
||||||
|
|
||||||
if (!_currSetup->_bkgndBm) {
|
|
||||||
// This should fail softly, for some reason jumping to the signpost (sg) will load
|
|
||||||
// the scene in such a way that the background isn't immediately available
|
|
||||||
warning("Background hasn't loaded yet for setup %s in %s!", _currSetup->_name.c_str(), _name.c_str());
|
|
||||||
} else {
|
|
||||||
_currSetup->_bkgndBm->draw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void drawBitmaps(ObjectState::Position stage);
|
void drawBitmaps(ObjectState::Position stage);
|
||||||
void setupCamera() {
|
void setupCamera() {
|
||||||
_currSetup->setupCamera();
|
_currSetup->setupCamera();
|
||||||
|
@ -82,7 +73,7 @@ public:
|
||||||
}
|
}
|
||||||
Sector *getSectorBase(int id) {
|
Sector *getSectorBase(int id) {
|
||||||
if ((_numSectors >= 0) && (id < _numSectors))
|
if ((_numSectors >= 0) && (id < _numSectors))
|
||||||
return &_sectors[id];
|
return _sectors[id];
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +97,7 @@ public:
|
||||||
void load(TextSplitter &ts);
|
void load(TextSplitter &ts);
|
||||||
void setupCamera() const;
|
void setupCamera() const;
|
||||||
Common::String _name;
|
Common::String _name;
|
||||||
Bitmap *_bkgndBm, *_bkgndZBm;
|
BitmapPtr _bkgndBm, _bkgndZBm;
|
||||||
Graphics::Vector3d _pos, _interest;
|
Graphics::Vector3d _pos, _interest;
|
||||||
float _roll, _fov, _nclip, _fclip;
|
float _roll, _fov, _nclip, _fclip;
|
||||||
};
|
};
|
||||||
|
@ -126,10 +117,10 @@ private:
|
||||||
|
|
||||||
Common::String _name;
|
Common::String _name;
|
||||||
int _numCmaps;
|
int _numCmaps;
|
||||||
CMap **_cmaps;
|
CMapPtr *_cmaps;
|
||||||
int _numSetups, _numLights, _numSectors, _numObjectStates;
|
int _numSetups, _numLights, _numSectors, _numObjectStates;
|
||||||
bool _enableLights;
|
bool _enableLights;
|
||||||
Sector *_sectors;
|
Sector **_sectors;
|
||||||
Light *_lights;
|
Light *_lights;
|
||||||
Setup *_setups;
|
Setup *_setups;
|
||||||
public:
|
public:
|
||||||
|
@ -137,6 +128,11 @@ public:
|
||||||
private:
|
private:
|
||||||
typedef Common::List<ObjectState*> StateList;
|
typedef Common::List<ObjectState*> StateList;
|
||||||
StateList _states;
|
StateList _states;
|
||||||
|
|
||||||
|
int _id;
|
||||||
|
static int s_id;
|
||||||
|
|
||||||
|
friend class GrimEngine;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
int TextObject::s_id = 0;
|
||||||
|
|
||||||
Common::String parseMsgText(const char *msg, char *msgId);
|
Common::String parseMsgText(const char *msg, char *msgId);
|
||||||
|
|
||||||
TextObjectDefaults sayLineDefaults;
|
TextObjectDefaults sayLineDefaults;
|
||||||
|
@ -37,7 +39,7 @@ TextObjectDefaults printLineDefaults;
|
||||||
TextObjectDefaults blastTextDefaults;
|
TextObjectDefaults blastTextDefaults;
|
||||||
|
|
||||||
TextObject::TextObject(bool blastDraw, bool isSpeech) :
|
TextObject::TextObject(bool blastDraw, bool isSpeech) :
|
||||||
_created(false), _x(0), _y(0), _width(0), _height(0), _justify(0),
|
Object(), _created(false), _x(0), _y(0), _width(0), _height(0), _justify(0),
|
||||||
_numberLines(1), _disabled(false), _font(NULL), _textBitmap(NULL),
|
_numberLines(1), _disabled(false), _font(NULL), _textBitmap(NULL),
|
||||||
_bitmapWidthPtr(NULL), _textObjectHandle(NULL) {
|
_bitmapWidthPtr(NULL), _textObjectHandle(NULL) {
|
||||||
memset(_textID, 0, sizeof(_textID));
|
memset(_textID, 0, sizeof(_textID));
|
||||||
|
@ -46,6 +48,14 @@ TextObject::TextObject(bool blastDraw, bool isSpeech) :
|
||||||
_fgColor._vals[2] = 0;
|
_fgColor._vals[2] = 0;
|
||||||
_blastDraw = blastDraw;
|
_blastDraw = blastDraw;
|
||||||
_isSpeech = isSpeech;
|
_isSpeech = isSpeech;
|
||||||
|
|
||||||
|
++s_id;
|
||||||
|
_id = s_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextObject::TextObject() :
|
||||||
|
Object(), _textObjectHandle(NULL), _bitmapWidthPtr(NULL) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextObject::setText(const char *text) {
|
void TextObject::setText(const char *text) {
|
||||||
|
@ -64,26 +74,53 @@ TextObject::~TextObject() {
|
||||||
destroyBitmap();
|
destroyBitmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextObject::saveState(SaveGame *savedState) {
|
void TextObject::saveState(SaveGame *state) const {
|
||||||
int32 size;
|
// state->writeLESint32(_created);
|
||||||
PointerId ptr;
|
|
||||||
|
|
||||||
size = strlen(_textID);
|
state->writeColor(_fgColor);
|
||||||
savedState->writeLESint32(size);
|
|
||||||
savedState->write(_textID, size);
|
state->writeLESint32(_x);
|
||||||
ptr = makeIdFromPointer(_font);
|
state->writeLESint32(_y);
|
||||||
savedState->writeLEUint32(ptr.low);
|
state->writeLESint32(_width);
|
||||||
savedState->writeLEUint32(ptr.hi);
|
state->writeLESint32(_height);
|
||||||
savedState->writeLEUint32(_blastDraw);
|
state->writeLESint32(_justify);
|
||||||
savedState->writeLEUint32(_disabled);
|
state->writeLESint32(_numberLines);
|
||||||
savedState->writeLEUint32(_justify);
|
|
||||||
savedState->writeLEUint32(_width);
|
state->writeLESint32(_disabled);
|
||||||
savedState->writeLEUint32(_height);
|
state->writeLESint32(_blastDraw);
|
||||||
savedState->writeLEUint32(_x);
|
state->writeLESint32(_isSpeech);
|
||||||
savedState->writeLEUint32(_y);
|
|
||||||
savedState->writeLEUint32(_fgColor.red());
|
state->writeString(_font->getFilename());
|
||||||
savedState->writeLEUint32(_fgColor.green());
|
|
||||||
savedState->writeLEUint32(_fgColor.blue());
|
state->write(_textID, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextObject::restoreState(SaveGame *state) {
|
||||||
|
// _created = state->readLESint32();
|
||||||
|
|
||||||
|
_fgColor = state->readColor();
|
||||||
|
|
||||||
|
_x = state->readLESint32();
|
||||||
|
_y = state->readLESint32();
|
||||||
|
_width = state->readLESint32();
|
||||||
|
_height = state->readLESint32();
|
||||||
|
_justify = state->readLESint32();
|
||||||
|
_numberLines = state->readLESint32();
|
||||||
|
|
||||||
|
_disabled = state->readLESint32();
|
||||||
|
_blastDraw = state->readLESint32();
|
||||||
|
_isSpeech = state->readLESint32();
|
||||||
|
|
||||||
|
_font = g_resourceloader->getFont(state->readString().c_str());
|
||||||
|
|
||||||
|
state->read(_textID, 256);
|
||||||
|
|
||||||
|
_created = false;
|
||||||
|
_textBitmap = NULL;
|
||||||
|
_textObjectHandle = NULL;
|
||||||
|
_bitmapWidthPtr = NULL;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextObject::setDefaults(TextObjectDefaults *defaults) {
|
void TextObject::setDefaults(TextObjectDefaults *defaults) {
|
||||||
|
@ -178,7 +215,7 @@ void TextObject::createBitmap() {
|
||||||
lineWidth -= MAX(_font->getCharWidth(msg[i]), _font->getCharDataWidth(msg[i]));
|
lineWidth -= MAX(_font->getCharWidth(msg[i]), _font->getCharDataWidth(msg[i]));
|
||||||
message.deleteLastChar();
|
message.deleteLastChar();
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
} else if (msg[i] != ' ') { // if it is a unique word
|
} else if (msg[i] != ' ') { // if it is a unique word
|
||||||
int dashWidth = MAX(_font->getCharWidth('-'), _font->getCharDataWidth('-'));
|
int dashWidth = MAX(_font->getCharWidth('-'), _font->getCharDataWidth('-'));
|
||||||
while (lineWidth + dashWidth > maxWidth) {
|
while (lineWidth + dashWidth > maxWidth) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ struct TextObjectDefaults {
|
||||||
int width, height;
|
int width, height;
|
||||||
int justify;
|
int justify;
|
||||||
bool disabled;
|
bool disabled;
|
||||||
Font *font;
|
FontPtr font;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TEXT_NULL ' '
|
#define TEXT_NULL ' '
|
||||||
|
@ -48,9 +48,11 @@ extern TextObjectDefaults sayLineDefaults;
|
||||||
extern TextObjectDefaults printLineDefaults;
|
extern TextObjectDefaults printLineDefaults;
|
||||||
extern TextObjectDefaults blastTextDefaults;
|
extern TextObjectDefaults blastTextDefaults;
|
||||||
|
|
||||||
class TextObject {
|
class TextObject : public Object {
|
||||||
|
GRIM_OBJECT(TextObject)
|
||||||
public:
|
public:
|
||||||
TextObject(bool blastDraw, bool isSpeech = false);
|
TextObject(bool blastDraw, bool isSpeech = false);
|
||||||
|
TextObject();
|
||||||
~TextObject();
|
~TextObject();
|
||||||
void createBitmap();
|
void createBitmap();
|
||||||
void destroyBitmap();
|
void destroyBitmap();
|
||||||
|
@ -79,11 +81,13 @@ public:
|
||||||
int getBitmapWidth();
|
int getBitmapWidth();
|
||||||
int getBitmapHeight();
|
int getBitmapHeight();
|
||||||
int getTextCharPosition(int pos);
|
int getTextCharPosition(int pos);
|
||||||
void saveState(SaveGame *savedState);
|
|
||||||
|
|
||||||
const char *name() const { return _textID; }
|
const char *name() const { return _textID; }
|
||||||
void draw();
|
void draw();
|
||||||
|
|
||||||
|
void saveState(SaveGame *state) const;
|
||||||
|
bool restoreState(SaveGame *state);
|
||||||
|
|
||||||
enum Justify {
|
enum Justify {
|
||||||
NONE,
|
NONE,
|
||||||
CENTER,
|
CENTER,
|
||||||
|
@ -100,11 +104,16 @@ protected:
|
||||||
bool _disabled;
|
bool _disabled;
|
||||||
bool _blastDraw;
|
bool _blastDraw;
|
||||||
bool _isSpeech;
|
bool _isSpeech;
|
||||||
Font *_font;
|
FontPtr _font;
|
||||||
char _textID[256];
|
char _textID[256];
|
||||||
uint8 *_textBitmap;
|
uint8 *_textBitmap;
|
||||||
int *_bitmapWidthPtr;
|
int *_bitmapWidthPtr;
|
||||||
GfxBase::TextObjectHandle **_textObjectHandle;
|
GfxBase::TextObjectHandle **_textObjectHandle;
|
||||||
|
|
||||||
|
int _id;
|
||||||
|
static int s_id;
|
||||||
|
|
||||||
|
friend class GrimEngine;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -28,9 +28,53 @@
|
||||||
#include "engines/grim/grim.h"
|
#include "engines/grim/grim.h"
|
||||||
#include "engines/grim/walkplane.h"
|
#include "engines/grim/walkplane.h"
|
||||||
#include "engines/grim/textsplit.h"
|
#include "engines/grim/textsplit.h"
|
||||||
|
#include "engines/grim/savegame.h"
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
void Sector::saveState(SaveGame *savedState) const {
|
||||||
|
savedState->writeLESint32(_numVertices);
|
||||||
|
savedState->writeLESint32(_id);
|
||||||
|
savedState->writeLESint32(_type);
|
||||||
|
savedState->writeLESint32(_visible);
|
||||||
|
savedState->writeFloat(_height);
|
||||||
|
|
||||||
|
const char *str = _name.c_str();
|
||||||
|
int32 size = strlen(str);
|
||||||
|
savedState->writeLESint32(size);
|
||||||
|
savedState->write(str, size);
|
||||||
|
|
||||||
|
for (int i = 0; i < _numVertices + 1; ++i) {
|
||||||
|
savedState->writeVector3d(_vertices[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
savedState->writeVector3d(_normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sector::restoreState(SaveGame *savedState) {
|
||||||
|
_numVertices = savedState->readLESint32();
|
||||||
|
_id = savedState->readLESint32();
|
||||||
|
_type = savedState->readLESint32();
|
||||||
|
_visible = savedState->readLESint32();
|
||||||
|
_height = savedState->readFloat();
|
||||||
|
|
||||||
|
int32 size = savedState->readLESint32();
|
||||||
|
char *str = new char[size+1];
|
||||||
|
savedState->read(str, size);
|
||||||
|
str[size]='\0';
|
||||||
|
_name = str;
|
||||||
|
delete[] str;
|
||||||
|
|
||||||
|
_vertices = new Graphics::Vector3d[_numVertices + 1];
|
||||||
|
for (int i = 0; i < _numVertices + 1; ++i) {
|
||||||
|
_vertices[i] = savedState->readVector3d();
|
||||||
|
}
|
||||||
|
|
||||||
|
_normal = savedState->readVector3d();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Sector::load(TextSplitter &ts) {
|
void Sector::load(TextSplitter &ts) {
|
||||||
char buf[256];
|
char buf[256];
|
||||||
int ident = 0, i = 0;
|
int ident = 0, i = 0;
|
||||||
|
@ -108,7 +152,6 @@ bool Sector::isPointInSector(Graphics::Vector3d point) const {
|
||||||
// z-coordinates so the railing in Cafe Calavera works properly.
|
// z-coordinates so the railing in Cafe Calavera works properly.
|
||||||
if (_height != 0.0f && _height != 9999.0f) {
|
if (_height != 0.0f && _height != 9999.0f) {
|
||||||
bool heightOK = false;
|
bool heightOK = false;
|
||||||
|
|
||||||
// Handle height above Z
|
// Handle height above Z
|
||||||
if ((point.z() >= _vertices[0].z()) && (point.z() <= _vertices[0].z() + _height))
|
if ((point.z() >= _vertices[0].z()) && (point.z() <= _vertices[0].z() + _height))
|
||||||
heightOK = true;
|
heightOK = true;
|
||||||
|
|
|
@ -32,12 +32,16 @@
|
||||||
|
|
||||||
namespace Grim {
|
namespace Grim {
|
||||||
|
|
||||||
|
class SaveGame;
|
||||||
class TextSplitter;
|
class TextSplitter;
|
||||||
|
|
||||||
class Sector {
|
class Sector {
|
||||||
public:
|
public:
|
||||||
Sector() : _vertices(0) {}
|
Sector() : _vertices(NULL) {}
|
||||||
~Sector() { if (_vertices) delete[] _vertices; }
|
virtual ~Sector() { if (_vertices) delete[] _vertices; }
|
||||||
|
|
||||||
|
void saveState(SaveGame *savedState) const;
|
||||||
|
bool restoreState(SaveGame *savedState);
|
||||||
|
|
||||||
void load(TextSplitter &ts);
|
void load(TextSplitter &ts);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue