format "_" in names,

format code a bit
This commit is contained in:
Pawel Kolodziejski 2004-12-09 23:55:43 +00:00
parent 06935dace4
commit 39a4b54d30
50 changed files with 1817 additions and 1862 deletions

396
actor.cpp
View File

@ -30,87 +30,88 @@
extern SoundMixer *g_mixer;
Actor::Actor(const char *name) :
name_(name), talkColor_(255, 255, 255), pos_(0, 0, 0),
pitch_(0), yaw_(0), roll_(0), walkRate_(0), turnRate_(0),
visible_(true), talkSound_(NULL), lipSynch_(NULL), turning_(false), walking_(false),
restCostume_(NULL), restChore_(-1),
walkCostume_(NULL), walkChore_(-1), walkedLast_(false), walkedCur_(false),
turnCostume_(NULL), leftTurnChore_(-1), rightTurnChore_(-1),
lastTurnDir_(0), currTurnDir_(0),
mumbleCostume_(NULL), mumbleChore_(-1) {
_name(name), _talkColor(255, 255, 255), _pos(0, 0, 0),
_pitch(0), _yaw(0), _roll(0), _walkRate(0), _turnRate(0),
_visible(true), _talkSound(NULL), _lipSynch(NULL), _turning(false), _walking(false),
_restCostume(NULL), _restChore(-1),
_walkCostume(NULL), _walkChore(-1), _walkedLast(false), _walkedCur(false),
_turnCostume(NULL), _leftTurnChore(-1), _rightTurnChore(-1),
_lastTurnDir(0), _currTurnDir(0),
_mumbleCostume(NULL), _mumbleChore(-1) {
Engine::instance()->registerActor(this);
lookingMode_ = false;
constrain_ = false;
_lookingMode = false;
_constrain = false;
for (int i = 0; i < 10; i++) {
talkCostume_[i] = NULL;
talkChore_[i] = -1;
_talkCostume[i] = NULL;
_talkChore[i] = -1;
}
}
void Actor::turnTo(float pitch, float yaw, float roll) {
pitch_ = pitch;
roll_ = roll;
if (yaw_ != yaw) {
turning_ = true;
destYaw_ = yaw;
_pitch = pitch;
_roll = roll;
if (_yaw != yaw) {
_turning = true;
_destYaw = yaw;
} else
turning_ = false;
_turning = false;
}
void Actor::walkTo(Vector3d p) {
// For now, this is just the ignoring-boxes version (which afaict
// isn't even in the original). This will eventually need a
// following-boxes version also.
if (p == pos_)
walking_ = false;
if (p == _pos)
_walking = false;
else {
walking_ = true;
destPos_ = p;
_walking = true;
_destPos = p;
if (p.x() != pos_.x() || p.y() != pos_.y())
turnTo(pitch_, yawTo(p), roll_);
if (p.x() != _pos.x() || p.y() != _pos.y())
turnTo(_pitch, yawTo(p), _roll);
}
}
bool Actor::isWalking() const {
return walkedLast_ || walkedCur_ || walking_;
return _walkedLast || _walkedCur || _walking;
}
bool Actor::isTurning() const {
if (turning_)
if (_turning)
return true;
if (lastTurnDir_ != 0 || currTurnDir_ != 0)
if (_lastTurnDir != 0 || _currTurnDir != 0)
return true;
return false;
}
void Actor::walkForward() {
float dist = Engine::instance()->perSecond(walkRate_);
float yaw_rad = yaw_ * (M_PI / 180), pitch_rad = pitch_ * (M_PI / 180);
float dist = Engine::instance()->perSecond(_walkRate);
float yaw_rad = _yaw * (M_PI / 180), pitch_rad = _pitch * (M_PI / 180);
Vector3d forwardVec(-std::sin(yaw_rad) * std::cos(pitch_rad),
std::cos(yaw_rad) * std::cos(pitch_rad),
std::sin(pitch_rad));
Vector3d destPos = pos_ + forwardVec * dist;
Vector3d destPos = _pos + forwardVec * dist;
if (! constrain_) {
pos_ = destPos;
walkedCur_ = true;
}
else {
if (!_constrain) {
_pos = destPos;
_walkedCur = true;
} else {
Sector *sector = Engine::instance()->currScene()->findPointSector(destPos, 0x1000);
if (sector != NULL) {
pos_ = sector->projectToPlane(destPos);
walkedCur_ = true;
_pos = sector->projectToPlane(destPos);
_walkedCur = true;
}
}
}
Vector3d Actor::puckVector() const {
float yaw_rad = yaw_ * (M_PI / 180);
float yaw_rad = _yaw * (M_PI / 180);
Vector3d forwardVec(-std::sin(yaw_rad), std::cos(yaw_rad), 0);
Sector *sector = Engine::instance()->currScene()->findPointSector(pos_, 0x1000);
Sector *sector = Engine::instance()->currScene()->findPointSector(_pos, 0x1000);
if (sector == NULL)
return forwardVec;
else
@ -118,77 +119,90 @@ Vector3d Actor::puckVector() const {
}
void Actor::setRestChore(int chore, Costume *cost) {
if (restCostume_ == cost && restChore_ == chore)
if (_restCostume == cost && _restChore == chore)
return;
if (restChore_ >= 0)
restCostume_->stopChore(restChore_);
restCostume_ = cost;
restChore_ = chore;
if (restChore_ >= 0)
restCostume_->playChoreLooping(restChore_);
if (_restChore >= 0)
_restCostume->stopChore(_restChore);
_restCostume = cost;
_restChore = chore;
if (_restChore >= 0)
_restCostume->playChoreLooping(_restChore);
}
void Actor::setWalkChore(int chore, Costume *cost) {
if (walkCostume_ == cost && walkChore_ == chore)
if (_walkCostume == cost && _walkChore == chore)
return;
if (walkChore_ >= 0)
walkCostume_->stopChore(walkChore_);
walkCostume_ = cost;
walkChore_ = chore;
if (_walkChore >= 0)
_walkCostume->stopChore(_walkChore);
_walkCostume = cost;
_walkChore = chore;
}
void Actor::setTurnChores(int left_chore, int right_chore, Costume *cost) {
if (turnCostume_ == cost && leftTurnChore_ == left_chore &&
rightTurnChore_ == right_chore)
if (_turnCostume == cost && _leftTurnChore == left_chore &&
_rightTurnChore == right_chore)
return;
if (leftTurnChore_ >= 0) {
turnCostume_->stopChore(leftTurnChore_);
turnCostume_->stopChore(rightTurnChore_);
}
turnCostume_ = cost;
leftTurnChore_ = left_chore;
rightTurnChore_ = right_chore;
if ((left_chore >= 0 && right_chore < 0) ||
(left_chore < 0 && right_chore >= 0))
if (_leftTurnChore >= 0) {
_turnCostume->stopChore(_leftTurnChore);
_turnCostume->stopChore(_rightTurnChore);
}
_turnCostume = cost;
_leftTurnChore = left_chore;
_rightTurnChore = right_chore;
if ((left_chore >= 0 && right_chore < 0) || (left_chore < 0 && right_chore >= 0))
error("Unexpectedly got only one turn chore\n");
}
void Actor::setTalkChore(int index, int chore, Costume *cost) {
if (index < 1 || index > 10)
error("Got talk chore index out of range (%d)\n", index);
index--;
if (talkCostume_[index] == cost && talkChore_[index] == chore)
if (_talkCostume[index] == cost && _talkChore[index] == chore)
return;
if (talkChore_[index] >= 0)
talkCostume_[index]->stopChore(talkChore_[index]);
talkCostume_[index] = cost;
talkChore_[index] = chore;
if (_talkChore[index] >= 0)
_talkCostume[index]->stopChore(_talkChore[index]);
_talkCostume[index] = cost;
_talkChore[index] = chore;
}
void Actor::setMumbleChore(int chore, Costume *cost) {
if (mumbleChore_ >= 0)
mumbleCostume_->stopChore(mumbleChore_);
mumbleCostume_ = cost;
mumbleChore_ = chore;
if (_mumbleChore >= 0)
_mumbleCostume->stopChore(_mumbleChore);
_mumbleCostume = cost;
_mumbleChore = chore;
}
void Actor::turn(int dir) {
float delta = Engine::instance()->perSecond(turnRate_) * dir;
yaw_ += delta;
currTurnDir_ = dir;
float delta = Engine::instance()->perSecond(_turnRate) * dir;
_yaw += delta;
_currTurnDir = dir;
}
float Actor::angleTo(const Actor &a) const {
float yaw_rad = yaw_ * (M_PI / 180);
float yaw_rad = _yaw * (M_PI / 180);
Vector3d forwardVec(-std::sin(yaw_rad), std::cos(yaw_rad), 0);
Vector3d delta = a.pos() - pos_;
Vector3d delta = a.pos() - _pos;
delta.z() = 0;
return angle(forwardVec, delta) * (180 / M_PI);
}
float Actor::yawTo(Vector3d p) const {
Vector3d dpos = p - pos_;
Vector3d dpos = p - _pos;
if (dpos.x() == 0 && dpos.y() == 0)
return 0;
else
@ -201,102 +215,108 @@ void Actor::sayLine(const char *msg) {
// Find the message identifier
if (msg[0] != '/')
return;
const char *secondSlash = std::strchr(msg + 1, '/');
if (secondSlash == NULL)
return;
if (talkSound_) // Only one line at a time, please :)
if (_talkSound) // Only one line at a time, please :)
shutUp();
std::string msgText = Localizer::instance()->localize(secondSlash + 1);
std::string msgId(msg + 1, secondSlash);
talkSound_ = ResourceLoader::instance()->loadSound((msgId + ".wav").c_str());
lipSynch_ = ResourceLoader::instance()->loadLipSynch((msgId + ".lip").c_str());
_talkSound = ResourceLoader::instance()->loadSound((msgId + ".wav").c_str());
_lipSynch = ResourceLoader::instance()->loadLipSynch((msgId + ".lip").c_str());
if (talkSound_ != NULL) {
Mixer::instance()->playVoice(talkSound_);
if (_talkSound != NULL) {
Mixer::instance()->playVoice(_talkSound);
// Sometimes actors speak offscreen before they, including their
// talk chores are initialized.
// For example, when reading the work order (a LIP file exists for no reason).
// Also, some lip synch files have no entries
// In these case, revert to using the mumble chore.
if (lipSynch_ != NULL && lipSynch_->getStatus()) {
talkAnim_ = lipSynch_->getCurrEntry().anim;
if (talkChore_[talkAnim_] >= 0) {
talkCostume_[talkAnim_]->playChoreLooping(talkChore_[talkAnim_]);
lipSynch_->advanceEntry();
if (_lipSynch != NULL && _lipSynch->getStatus()) {
_talkAnim = _lipSynch->getCurrEntry().anim;
if (_talkChore[_talkAnim] >= 0) {
_talkCostume[_talkAnim]->playChoreLooping(_talkChore[_talkAnim]);
_lipSynch->advanceEntry();
}
} else {
lipSynch_ = NULL;
if (mumbleChore_ >= 0)
mumbleCostume_->playChoreLooping(mumbleChore_);
_lipSynch = NULL;
if (_mumbleChore >= 0)
_mumbleCostume->playChoreLooping(_mumbleChore);
}
}
}
bool Actor::talking() {
return (talkSound_ != NULL && ! talkSound_->done());
return (_talkSound != NULL && !_talkSound->done());
}
void Actor::shutUp() {
if (talkSound_) {
Mixer::instance()->stopVoice(talkSound_);
if (lipSynch_ != NULL) {
if (talkChore_[talkAnim_] >= 0)
talkCostume_[talkAnim_]->stopChore(talkChore_[talkAnim_]);
lipSynch_ = NULL;
} else if (mumbleChore_ >= 0)
mumbleCostume_->stopChore(mumbleChore_);
talkSound_ = NULL;
if (_talkSound) {
Mixer::instance()->stopVoice(_talkSound);
if (_lipSynch != NULL) {
if (_talkChore[_talkAnim] >= 0)
_talkCostume[_talkAnim]->stopChore(_talkChore[_talkAnim]);
_lipSynch = NULL;
} else if (_mumbleChore >= 0)
_mumbleCostume->stopChore(_mumbleChore);
_talkSound = NULL;
}
}
void Actor::pushCostume(const char *name) {
Costume *newCost = ResourceLoader::instance()->
loadCostume(name, currentCostume());
costumeStack_.push_back(newCost);
Costume *newCost = ResourceLoader::instance()->loadCostume(name, currentCostume());
_costumeStack.push_back(newCost);
}
void Actor::setCostume(const char *name) {
if (! costumeStack_.empty())
if (!_costumeStack.empty())
popCostume();
pushCostume(name);
}
void Actor::popCostume() {
if (! costumeStack_.empty()) {
freeCostumeChore(costumeStack_.back(), restCostume_, restChore_);
freeCostumeChore(costumeStack_.back(), walkCostume_, walkChore_);
if (turnCostume_ == costumeStack_.back()) {
turnCostume_ = NULL;
leftTurnChore_ = -1;
rightTurnChore_ = -1;
if (!_costumeStack.empty()) {
freeCostumeChore(_costumeStack.back(), _restCostume, _restChore);
freeCostumeChore(_costumeStack.back(), _walkCostume, _walkChore);
if (_turnCostume == _costumeStack.back()) {
_turnCostume = NULL;
_leftTurnChore = -1;
_rightTurnChore = -1;
}
freeCostumeChore(costumeStack_.back(), mumbleCostume_, mumbleChore_);
freeCostumeChore(_costumeStack.back(), _mumbleCostume, _mumbleChore);
for (int i = 0; i < 10; i++)
freeCostumeChore(costumeStack_.back(), talkCostume_[i], talkChore_[i]);
delete costumeStack_.back();
costumeStack_.pop_back();
freeCostumeChore(_costumeStack.back(), _talkCostume[i], _talkChore[i]);
delete _costumeStack.back();
_costumeStack.pop_back();
}
}
void Actor::clearCostumes() {
// Make sure to destroy costume copies in reverse order
while (! costumeStack_.empty())
while (!_costumeStack.empty())
popCostume();
}
void Actor::setHead( int joint1, int joint2, int joint3, float maxRoll, float maxPitch, float maxYaw ) {
if (!costumeStack_.empty()) {
costumeStack_.back()->setHead( joint1, joint2, joint3, maxRoll, maxPitch, maxYaw);
if (!_costumeStack.empty()) {
_costumeStack.back()->setHead(joint1, joint2, joint3, maxRoll, maxPitch, maxYaw);
}
}
Costume *Actor::findCostume(const char *name) {
for (std::list<Costume *>::iterator i = costumeStack_.begin();
i != costumeStack_.end(); i++)
for (std::list<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); i++)
if (std::strcmp((*i)->filename(), name) == 0)
return *i;
return NULL;
}
@ -304,118 +324,116 @@ void Actor::update() {
// Snap actor to walkboxes if following them. This might be
// necessary for example after activating/deactivating
// walkboxes, etc.
if (constrain_ && ! walking_) {
Engine::instance()->currScene()->findClosestSector(pos_, NULL, &pos_);
if (_constrain && !_walking) {
Engine::instance()->currScene()->findClosestSector(_pos, NULL, &_pos);
}
if (turning_) {
float turnAmt = Engine::instance()->perSecond(turnRate_);
float dyaw = destYaw_ - yaw_;
if (_turning) {
float turnAmt = Engine::instance()->perSecond(_turnRate);
float dyaw = _destYaw - _yaw;
while (dyaw > 180)
dyaw -= 360;
while (dyaw < -180)
dyaw += 360;
if (turnAmt >= std::abs(dyaw)) {
yaw_ = destYaw_;
turning_ = false;
_yaw = _destYaw;
_turning = false;
}
else if (dyaw > 0)
yaw_ += turnAmt;
_yaw += turnAmt;
else
yaw_ -= turnAmt;
currTurnDir_ = (dyaw > 0 ? 1 : -1);
_yaw -= turnAmt;
_currTurnDir = (dyaw > 0 ? 1 : -1);
}
if (walking_) {
Vector3d dir = destPos_ - pos_;
if (_walking) {
Vector3d dir = _destPos - _pos;
float dist = dir.magnitude();
if (dist > 0)
dir /= dist;
float walkAmt = Engine::instance()->perSecond(walkRate_);
float walkAmt = Engine::instance()->perSecond(_walkRate);
if (walkAmt >= dist) {
pos_ = destPos_;
walking_ = false;
turning_ = false;
}
else
pos_ += dir * walkAmt;
_pos = _destPos;
_walking = false;
_turning = false;
} else
_pos += dir * walkAmt;
walkedCur_ = true;
_walkedCur = true;
}
// The rest chore might have been stopped because of a
// StopActorChore(nil). Restart it if so.
if (restChore_ >= 0 && restCostume_->isChoring(restChore_, false) < 0)
restCostume_->playChoreLooping(restChore_);
if (_restChore >= 0 && _restCostume->isChoring(_restChore, false) < 0)
_restCostume->playChoreLooping(_restChore);
if (walkChore_ >= 0) {
if (walkedCur_) {
if (walkCostume_->isChoring(walkChore_, false) < 0)
walkCostume_->playChoreLooping(walkChore_);
}
else {
if (walkCostume_->isChoring(walkChore_, false) >= 0)
walkCostume_->stopChore(walkChore_);
if (_walkChore >= 0) {
if (_walkedCur) {
if (_walkCostume->isChoring(_walkChore, false) < 0)
_walkCostume->playChoreLooping(_walkChore);
} else {
if (_walkCostume->isChoring(_walkChore, false) >= 0)
_walkCostume->stopChore(_walkChore);
}
}
if (leftTurnChore_ >= 0) {
if (walkedCur_)
currTurnDir_ = 0;
if (lastTurnDir_ != 0 && lastTurnDir_ != currTurnDir_)
turnCostume_->stopChore(getTurnChore(lastTurnDir_));
if (currTurnDir_ != 0 && currTurnDir_ != lastTurnDir_)
turnCostume_->playChoreLooping(getTurnChore(currTurnDir_));
}
else
currTurnDir_ = 0;
walkedLast_ = walkedCur_;
walkedCur_ = false;
lastTurnDir_ = currTurnDir_;
currTurnDir_ = 0;
if (_leftTurnChore >= 0) {
if (_walkedCur)
_currTurnDir = 0;
if (_lastTurnDir != 0 && _lastTurnDir != _currTurnDir)
_turnCostume->stopChore(getTurnChore(_lastTurnDir));
if (_currTurnDir != 0 && _currTurnDir != _lastTurnDir)
_turnCostume->playChoreLooping(getTurnChore(_currTurnDir));
} else
_currTurnDir = 0;
_walkedLast = _walkedCur;
_walkedCur = false;
_lastTurnDir = _currTurnDir;
_currTurnDir = 0;
// Update lip synching
if (lipSynch_ != NULL && talkSound_ != NULL &&
talkSound_->hasReachedPos(lipSynch_->getCurrEntry().frame *
g_mixer->getOutputRate() / 60)) {
if (_lipSynch != NULL && _talkSound != NULL &&
_talkSound->hasReachedPos(_lipSynch->getCurrEntry().frame * g_mixer->getOutputRate() / 60)) {
///printf("Reached beyond frame %d (=pos %d). Playing anim %d\n",
// lipSynch_->getCurrEntry().frame, lipSynch_->getCurrEntry().frame *
// g_mixer->getOutputRate() / 60,lipSynch_->getCurrEntry().anim);
//printf("Reached beyond frame %d (=pos %d). Playing anim %d\n",
//_lipSynch->getCurrEntry().frame, _lipSynch->getCurrEntry().frame *
//g_mixer->getOutputRate() / 60, _lipSynch->getCurrEntry().anim);
if (talkChore_[talkAnim_] >= 0)
talkCostume_[talkAnim_]->stopChore(talkChore_[talkAnim_]);
talkAnim_ = lipSynch_->getCurrEntry().anim;
if (talkChore_[talkAnim_] >= 0)
talkCostume_[talkAnim_]->playChoreLooping(talkChore_[talkAnim_]);
lipSynch_->advanceEntry();
}
if (_talkChore[_talkAnim] >= 0)
_talkCostume[_talkAnim]->stopChore(_talkChore[_talkAnim]);
if (talkSound_ != NULL && talkSound_->done())
_talkAnim = _lipSynch->getCurrEntry().anim;
if (_talkChore[_talkAnim] >= 0)
_talkCostume[_talkAnim]->playChoreLooping(_talkChore[_talkAnim]);
_lipSynch->advanceEntry();
}
if (_talkSound != NULL && _talkSound->done())
shutUp();
for (std::list<Costume *>::iterator i = costumeStack_.begin();
i != costumeStack_.end(); i++) {
(*i)->setPosRotate( pos_, pitch_, yaw_, roll_ );
for (std::list<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); i++) {
(*i)->setPosRotate(_pos, _pitch, _yaw, _roll);
(*i)->update();
}
if (lookingMode_) {
float lookAtAmt = Engine::instance()->perSecond(lookAtRate_);
if (_lookingMode) {
float lookAtAmt = Engine::instance()->perSecond(_lookAtRate);
}
}
void Actor::draw() {
for (std::list<Costume *>::iterator i = costumeStack_.begin();
i != costumeStack_.end(); i++)
for (std::list<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); i++)
(*i)->setupTextures();
if (! costumeStack_.empty()) {
g_driver->startActorDraw(pos_, yaw_, pitch_, roll_);
costumeStack_.back()->draw();
if (!_costumeStack.empty()) {
g_driver->startActorDraw(_pos, _yaw, _pitch, _roll);
_costumeStack.back()->draw();
g_driver->finishActorDraw();
}
}
}

122
actor.h
View File

@ -32,36 +32,36 @@ class Actor {
public:
Actor(const char *name);
const char *name() const { return name_.c_str(); }
const char *name() const { return _name.c_str(); }
void setTalkColor(const Color& c) { talkColor_ = c; }
Color talkColor() const { return talkColor_; }
void setPos(Vector3d pos) { pos_ = pos; }
Vector3d pos() const { return pos_; }
void setTalkColor(const Color& c) { _talkColor = c; }
Color talkColor() const { return _talkColor; }
void setPos(Vector3d pos) { _pos = pos; }
Vector3d pos() const { return _pos; }
void walkTo(Vector3d p);
bool isWalking() const;
void setRot(float pitch, float yaw, float roll) {
pitch_ = pitch; yaw_ = yaw; roll_ = roll;
_pitch = pitch; _yaw = yaw; _roll = roll;
}
void turnTo(float pitch, float yaw, float roll);
bool isTurning() const;
float pitch() const { return pitch_; }
float yaw() const { return yaw_; }
float roll() const { return roll_; }
void setVisibility(bool val) { visible_ = val; }
bool visible() const { return visible_; }
void putInSet(const char *name) { setName_ = name; }
void setTurnRate(float rate) { turnRate_ = rate; }
float turnRate() const { return turnRate_; }
void setWalkRate(float rate) { walkRate_ = rate; }
float walkRate() const { return walkRate_; }
void setLooking(bool lookingMode) { lookingMode_ = lookingMode; }
float pitch() const { return _pitch; }
float yaw() const { return _yaw; }
float roll() const { return _roll; }
void setVisibility(bool val) { _visible = val; }
bool visible() const { return _visible; }
void putInSet(const char *name) { _setName = name; }
void setTurnRate(float rate) { _turnRate = rate; }
float turnRate() const { return _turnRate; }
void setWalkRate(float rate) { _walkRate = rate; }
float walkRate() const { return _walkRate; }
void setLooking(bool lookingMode) { _lookingMode = lookingMode; }
float angleTo(const Actor &a) const;
float yawTo(Vector3d p) const;
bool inSet(const char *name) const {
return setName_ == name;
return _setName == name;
}
void walkForward();
Vector3d puckVector() const;
@ -82,82 +82,82 @@ public:
void popCostume();
void clearCostumes();
Costume *currentCostume() {
if (costumeStack_.empty())
if (_costumeStack.empty())
return NULL;
else
return costumeStack_.back();
return _costumeStack.back();
}
Costume *findCostume(const char *name);
int costumeStackDepth() const {
return costumeStack_.size();
return _costumeStack.size();
}
void setConstrain(bool constrain) {
constrain_ = constrain;
_constrain = constrain;
}
void update();
void draw();
bool isLookAtVectorZero() {
return lookAtVector_.isZero();
return _lookAtVector.isZero();
}
void setLookAtVectorZero() {
lookAtVector_.set( 0.f, 0.f, 0.f );
_lookAtVector.set( 0.f, 0.f, 0.f );
}
void setLookAtVector( Vector3d vector ) {
lookAtVector_ = vector;
void setLookAtVector(Vector3d vector) {
_lookAtVector = vector;
}
void setLookAtRate( float rate ) {
lookAtRate_ = rate;
void setLookAtRate(float rate) {
_lookAtRate = rate;
}
float lookAtRate() {
return(lookAtRate_);
return _lookAtRate;
}
void setHead( int joint1, int joint2, int joint3, float maxRoll, float maxPitch, float maxYaw);
private:
std::string name_;
std::string setName_;
Color talkColor_;
Vector3d pos_;
float pitch_, yaw_, roll_;
float walkRate_, turnRate_;
std::string _name;
std::string _setName;
Color _talkColor;
Vector3d _pos;
float _pitch, _yaw, _roll;
float _walkRate, _turnRate;
bool constrain_; // Constrain to walkboxes
bool visible_;
bool lookingMode_;
ResPtr<Sound> talkSound_;
ResPtr<LipSynch> lipSynch_;
std::list<Costume *> costumeStack_;
bool _constrain; // Constrain to walkboxes
bool _visible;
bool _lookingMode;
ResPtr<Sound> _talkSound;
ResPtr<LipSynch> _lipSynch;
std::list<Costume *> _costumeStack;
// Variables for gradual turning
bool turning_;
float destYaw_;
bool _turning;
float _destYaw;
// Variables for walking to a point
bool walking_;
Vector3d destPos_;
bool _walking;
Vector3d _destPos;
// chores
Costume *restCostume_;
int restChore_;
Costume *_restCostume;
int _restChore;
Costume *walkCostume_;
int walkChore_;
bool walkedLast_, walkedCur_;
Costume *_walkCostume;
int _walkChore;
bool _walkedLast, _walkedCur;
Costume *turnCostume_;
int leftTurnChore_, rightTurnChore_;
int lastTurnDir_, currTurnDir_;
Costume *_turnCostume;
int _leftTurnChore, _rightTurnChore;
int _lastTurnDir, _currTurnDir;
Costume *talkCostume_[10];
int talkChore_[10];
int talkAnim_;
Costume *_talkCostume[10];
int _talkChore[10];
int _talkAnim;
Costume *mumbleCostume_;
int mumbleChore_;
Costume *_mumbleCostume;
int _mumbleChore;
int getTurnChore(int dir) {
return (dir > 0 ? rightTurnChore_ : leftTurnChore_);
return (dir > 0 ? _rightTurnChore : _leftTurnChore);
}
void freeCostumeChore(Costume *toFree, Costume *&cost, int &chore) {
@ -168,8 +168,8 @@ private:
}
// lookAt
Vector3d lookAtVector_;
float lookAtRate_;
Vector3d _lookAtVector;
float _lookAtRate;
friend class Engine;
};

View File

@ -30,54 +30,56 @@
static void decompress_codec3(const char *compressed, char *result);
Bitmap::Bitmap(const char *filename, const char *data, int len) :
Resource(filename) {
Resource(filename) {
if (len < 8 || memcmp(data, "BM F\0\0\0", 8) != 0)
error("Invalid magic loading bitmap\n");
int codec = READ_LE_UINT32(data + 8);
num_images_ = READ_LE_UINT32(data + 16);
x_ = READ_LE_UINT32(data + 20);
y_ = READ_LE_UINT32(data + 24);
format_ = READ_LE_UINT32(data + 32);
width_ = READ_LE_UINT32(data + 128);
height_ = READ_LE_UINT32(data + 132);
curr_image_ = 1;
_num_images = READ_LE_UINT32(data + 16);
_x = READ_LE_UINT32(data + 20);
_y = READ_LE_UINT32(data + 24);
_format = READ_LE_UINT32(data + 32);
_width = READ_LE_UINT32(data + 128);
_height = READ_LE_UINT32(data + 132);
_curr_image = 1;
data_ = new char*[num_images_];
_data = new char *[_num_images];
int pos = 0x88;
for (int i = 0; i < num_images_; i++) {
data_[i] = new char[2 * width_ * height_];
for (int i = 0; i < _num_images; i++) {
_data[i] = new char[2 * _width * _height];
if (codec == 0) {
memcpy(data_[i], data + pos, 2 * width_ * height_);
pos += 2 * width_ * height_ + 8;
memcpy(_data[i], data + pos, 2 * _width * _height);
pos += 2 * _width * _height + 8;
} else if (codec == 3) {
int compressed_len = READ_LE_UINT32(data + pos);
decompress_codec3(data + pos + 4, data_[i]);
pos += compressed_len + 12;
int compressed_len = READ_LE_UINT32(data + pos);
decompress_codec3(data + pos + 4, _data[i]);
pos += compressed_len + 12;
}
#ifdef SYSTEM_BIG_ENDIAN
if (format_ == 1)
for (int j = 0; j < width_ * height_; ++j) {
((uint16 *)data_[i])[j] = SWAP_BYTES_16(((uint16 *)data_[i])[j]);
#ifdef SYSTEM_BIG_ENDIAN
if (_format == 1)
for (int j = 0; j < _width * _height; ++j) {
((uint16 *)_data[i])[j] = SWAP_BYTES_16(((uint16 *)_data[i])[j]);
}
#endif
#endif
}
g_driver->createBitmap(this);
}
void Bitmap::draw() const {
if (curr_image_ == 0)
if (_curr_image == 0)
return;
g_driver->drawBitmap(this);
}
Bitmap::~Bitmap() {
for (int i = 0; i < num_images_; i++)
delete[] data_[i];
delete[] data_;
for (int i = 0; i < _num_images; i++)
delete[] _data[i];
delete[] _data;
g_driver->destroyBitmap(this);
}
@ -111,8 +113,7 @@ static void decompress_codec3(const char *compressed, char *result) {
copy_len += bit + 3;
copy_offset = *(uint8 *)(compressed++) - 0x100;
} else {
copy_offset = (*(uint8 *)(compressed) |
(*(uint8 *)(compressed + 1) & 0xf0) << 4) - 0x1000;
copy_offset = (*(uint8 *)(compressed) | (*(uint8 *)(compressed + 1) & 0xf0) << 4) - 0x1000;
copy_len = (*(uint8 *)(compressed + 1) & 0xf) + 3;
compressed += 2;
if (copy_len == 3) {
@ -121,10 +122,10 @@ static void decompress_codec3(const char *compressed, char *result) {
return;
}
}
while (copy_len > 0) {
*result = result[copy_offset];
result++;
copy_len--;
while (copy_len > 0) {
*result = result[copy_offset];
result++;
copy_len--;
}
}
}

View File

@ -30,28 +30,28 @@ public:
void draw() const;
// Set which image in an animated bitmap to use
void setNumber(int n) { curr_image_ = n; }
void setNumber(int n) { _curr_image = n; }
int numImages() const { return num_images_; }
int currentImage() const { return curr_image_; }
int numImages() const { return _num_images; }
int currentImage() const { return _curr_image; }
int width() const { return width_; }
int height() const { return height_; }
int x() const { return x_; }
int y() const { return y_; }
int width() const { return _width; }
int height() const { return _height; }
int x() const { return _x; }
int y() const { return _y; }
char * getData() { return data_[curr_image_]; }
char *getData() { return _data[_curr_image]; }
~Bitmap();
//private:
char **data_;
int num_images_, curr_image_;
int width_, height_, x_, y_;
int format_;
int num_tex_;
GLuint *tex_ids_;
bool hasTransparency_;
char **_data;
int _num_images, _curr_image;
int _width, _height, _x, _y;
int _format;
int _num_tex;
GLuint *_tex_ids;
bool _hasTransparency;
};
#endif

26
color.h
View File

@ -22,29 +22,29 @@
class Color {
public:
byte vals_[3];
byte _vals[3];
Color() {}
Color(byte r, byte g, byte b) {
vals_[0] = r; vals_[1] = g; vals_[2] = b;
_vals[0] = r; _vals[1] = g; _vals[2] = b;
}
Color(const Color& c) {
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];
}
byte &red() { return vals_[0]; }
byte red() const { return vals_[0]; }
byte &green() { return vals_[1]; }
byte green() const { return vals_[1]; }
byte &blue() { return vals_[2]; }
byte blue() const { return vals_[2]; }
byte &red() { return _vals[0]; }
byte red() const { return _vals[0]; }
byte &green() { return _vals[1]; }
byte green() const { return _vals[1]; }
byte &blue() { return _vals[2]; }
byte blue() const { return _vals[2]; }
Color& operator =(const Color &c) {
vals_[0] = c.vals_[0]; vals_[1] = c.vals_[1]; vals_[2] = c.vals_[2];
return *this;
}
_vals[0] = c._vals[0]; _vals[1] = c._vals[1]; _vals[2] = c._vals[2];
return *this;
}
Color& operator =(Color *c) {
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;
}
};

View File

@ -29,11 +29,11 @@ public:
Resource(filename) {
if (len < 4 || std::memcmp(data, "CMP ", 4) != 0)
error("Invalid magic loading colormap\n");
std::memcpy(colors, data + 64, sizeof(colors));
std::memcpy(_colors, data + 64, sizeof(_colors));
}
// The color data, in RGB format
char colors[256 * 3];
char _colors[256 * 3];
};
#endif

View File

@ -95,7 +95,7 @@ public:
void setKey(int val);
private:
std::string filename_;
std::string _filename;
};
class ModelComponent : public Costume::Component {
@ -106,18 +106,18 @@ public:
void update();
void reset();
void setColormap(CMap *c);
void setMatrix(Matrix4 matrix) { matrix_ = matrix; };
void setMatrix(Matrix4 matrix) { _matrix = matrix; };
~ModelComponent();
Model::HierNode *hierarchy() { return hier_; }
Model::HierNode *hierarchy() { return _hier; }
void draw();
protected:
std::string filename_;
ResPtr<Model> obj_;
ResPtr<CMap> cmap_;
Model::HierNode *hier_;
Matrix4 matrix_;
std::string _filename;
ResPtr<Model> _obj;
ResPtr<CMap> _cmap;
Model::HierNode *_hier;
Matrix4 _matrix;
};
class MainModelComponent : public ModelComponent {
@ -130,7 +130,7 @@ public:
~MainModelComponent();
private:
bool hierShared_;
bool _hierShared;
friend class Costume;
};
@ -144,120 +144,115 @@ public:
void reset();
~MeshComponent() { }
void setMatrix(Matrix4 matrix) { matrix_ = matrix; };
void setMatrix(Matrix4 matrix) { _matrix = matrix; };
Model::HierNode *node() { return node_; }
Model::HierNode *node() { return _node; }
private:
int num_;
Model::HierNode *node_;
Matrix4 matrix_;
int _num;
Model::HierNode *_node;
Matrix4 _matrix;
};
BitmapComponent::BitmapComponent(Costume::Component *parent, int parentID,
const char *filename) :
Costume::Component(parent, parentID), filename_(filename) {
BitmapComponent::BitmapComponent(Costume::Component *parent, int parentID, const char *filename) :
Costume::Component(parent, parentID), _filename(filename) {
}
void BitmapComponent::setKey(int val) {
ObjectState *state =
Engine::instance()->currScene()->findState(filename_.c_str());
ObjectState *state = Engine::instance()->currScene()->findState(_filename.c_str());
if (state != NULL)
state->setNumber(val);
else
warning("Couldn't find bitmap %s in current scene\n",
filename_.c_str());
warning("Couldn't find bitmap %s in current scene\n", _filename.c_str());
}
ModelComponent::ModelComponent(Costume::Component *parent, int parentID,
const char *filename) :
Costume::Component(parent, parentID), filename_(filename), obj_(NULL),
cmap_(NULL), hier_(NULL) {
ModelComponent::ModelComponent(Costume::Component *parent, int parentID, const char *filename) :
Costume::Component(parent, parentID), _filename(filename), _obj(NULL), _cmap(NULL), _hier(NULL) {
}
void ModelComponent::init() {
if (obj_ == NULL) {
if (_obj == NULL) {
// Skip loading if it was initialized
// by the sharing MainModelComponent
// constructor before
if (cmap_ == NULL) {
warning("No colormap specified for %s\n", filename_.c_str());
cmap_ = ResourceLoader::instance()->loadColormap("item.cmp");
if (_cmap == NULL) {
warning("No colormap specified for %s\n", _filename.c_str());
_cmap = ResourceLoader::instance()->loadColormap("item.cmp");
}
obj_ = ResourceLoader::instance()->loadModel(filename_.c_str(), *cmap_);
hier_ = obj_->copyHierarchy();
hier_->hierVisible_ = false;
}
_obj = ResourceLoader::instance()->loadModel(_filename.c_str(), *_cmap);
_hier = _obj->copyHierarchy();
_hier->_hierVisible = false;
}
// If we're the child of a mesh component, put our nodes in the
// parent object's tree.
if (parent_ != NULL) {
MeshComponent *mc = dynamic_cast<MeshComponent *>(parent_);
if (mc != NULL)
mc->node()->addChild(hier_);
else
warning("Parent of model %s wasn't a mesh\n", filename_.c_str());
// If we're the child of a mesh component, put our nodes in the
// parent object's tree.
if (_parent != NULL) {
MeshComponent *mc = dynamic_cast<MeshComponent *>(_parent);
if (mc != NULL)
mc->node()->addChild(_hier);
else
warning("Parent of model %s wasn't a mesh\n", _filename.c_str());
}
}
void ModelComponent::setKey(int val) {
hier_->hierVisible_ = (val != 0);
_hier->_hierVisible = (val != 0);
}
// Reset the hierarchy nodes for any keyframe animations (which
// are children of this component and therefore get updated later).
void ModelComponent::update() {
for (int i = 0; i < obj_->numNodes(); i++) {
hier_[i].priority_ = -1;
hier_[i].animPos_ = hier_[i].pos_;
hier_[i].animPitch_ = hier_[i].pitch_;
hier_[i].animYaw_ = hier_[i].yaw_;
hier_[i].animRoll_ = hier_[i].roll_;
hier_[i].totalWeight_ = 1;
for (int i = 0; i < _obj->numNodes(); i++) {
_hier[i]._priority = -1;
_hier[i]._animPos = _hier[i]._pos;
_hier[i]._animPitch = _hier[i]._pitch;
_hier[i]._animYaw = _hier[i]._yaw;
_hier[i]._animRoll = _hier[i]._roll;
_hier[i]._totalWeight = 1;
}
}
void ModelComponent::reset() {
hier_->hierVisible_ = false;
_hier->_hierVisible = false;
}
void ModelComponent::setColormap(CMap *c) {
cmap_ = c;
_cmap = c;
}
ModelComponent::~ModelComponent() {
if (hier_ != NULL && hier_->parent_ != NULL)
hier_->parent_->removeChild(hier_);
delete[] hier_;
if (_hier != NULL && _hier->_parent != NULL)
_hier->_parent->removeChild(_hier);
delete[] _hier;
}
void ModelComponent::draw() {
if (parent_ == NULL)
if (_parent == NULL)
// Otherwise it was already drawn by
// being included in the parent's hierarchy
hier_->draw();
_hier->draw();
}
MainModelComponent::MainModelComponent(Costume::Component *parent,
int parentID, const char *filename) :
ModelComponent(parent, parentID, filename), hierShared_(false) {
MainModelComponent::MainModelComponent(Costume::Component *parent, int parentID, const char *filename) :
ModelComponent(parent, parentID, filename), _hierShared(false) {
}
// Constructor used if sharing the main model with the previous costume
MainModelComponent::MainModelComponent(const char *filename, Model *prevObj,
Model::HierNode *prevHier) :
ModelComponent(NULL, -1, filename), hierShared_(true) {
obj_ = prevObj;
hier_ = prevHier;
MainModelComponent::MainModelComponent(const char *filename, Model *prevObj, Model::HierNode *prevHier) :
ModelComponent(NULL, -1, filename), _hierShared(true) {
_obj = prevObj;
_hier = prevHier;
}
void MainModelComponent::init() {
ModelComponent::init();
hier_->hierVisible_ = true;
_hier->_hierVisible = true;
}
void MainModelComponent::update() {
if (! hierShared_)
if (!_hierShared)
// Otherwise, it was already initialized
// and reinitializing it will destroy work
// from previous costumes
@ -265,12 +260,12 @@ void MainModelComponent::update() {
}
void MainModelComponent::reset() {
hier_->hierVisible_ = true;
_hier->_hierVisible = true;
}
MainModelComponent::~MainModelComponent() {
if (hierShared_)
hier_ = NULL; // Keep ~ModelComp from deleting it
if (_hierShared)
_hier = NULL; // Keep ~ModelComp from deleting it
}
class ColormapComponent : public Costume::Component {
@ -280,21 +275,20 @@ public:
~ColormapComponent();
private:
ResPtr<CMap> cmap_;
ResPtr<CMap> _cmap;
};
ColormapComponent::ColormapComponent(Costume::Component *parent,
int parentID, const char *filename) :
ColormapComponent::ColormapComponent(Costume::Component *parent, int parentID, const char *filename) :
Costume::Component(parent, parentID) {
cmap_ = ResourceLoader::instance()->loadColormap(filename);
_cmap = ResourceLoader::instance()->loadColormap(filename);
ModelComponent *mc = dynamic_cast<ModelComponent *>(parent);
if (mc != NULL)
mc->setColormap(cmap_);
mc->setColormap(_cmap);
}
ColormapComponent::~ColormapComponent() {
}
}
class KeyframeComponent : public Costume::Component {
public:
@ -306,25 +300,23 @@ public:
~KeyframeComponent() {}
private:
ResPtr<KeyframeAnim> keyf_;
int priority1_, priority2_;
Model::HierNode *hier_;
bool active_;
int repeatMode_;
int currTime_;
ResPtr<KeyframeAnim> _keyf;
int _priority1, _priority2;
Model::HierNode *_hier;
bool _active;
int _repeatMode;
int _currTime;
};
KeyframeComponent::KeyframeComponent(Costume::Component *parent, int parentID,
const char *filename) :
Costume::Component(parent, parentID), priority1_(1), priority2_(5),
hier_(NULL), active_(false) {
KeyframeComponent::KeyframeComponent(Costume::Component *parent, int parentID, const char *filename) :
Costume::Component(parent, parentID), _priority1(1), _priority2(5), _hier(NULL), _active(false) {
const char *comma = std::strchr(filename, ',');
if (comma != NULL) {
std::string realName(filename, comma);
keyf_ = ResourceLoader::instance()->loadKeyframe(realName.c_str());
std::sscanf(comma + 1, "%d,%d", &priority1_, &priority2_);
_keyf = ResourceLoader::instance()->loadKeyframe(realName.c_str());
std::sscanf(comma + 1, "%d,%d", &_priority1, &_priority2);
} else
keyf_ = ResourceLoader::instance()->loadKeyframe(filename);
_keyf = ResourceLoader::instance()->loadKeyframe(filename);
}
void KeyframeComponent::setKey(int val) {
@ -333,94 +325,96 @@ void KeyframeComponent::setKey(int val) {
case 1:
case 2:
case 3:
if (! active_ || val != 1) {
active_ = true;
currTime_ = -1;
if (!_active || val != 1) {
_active = true;
_currTime = -1;
}
repeatMode_ = val;
_repeatMode = val;
break;
case 4:
active_ = false;
_active = false;
break;
default:
warning("Unknown key %d for keyframe %s\n", val, keyf_->filename());
warning("Unknown key %d for keyframe %s\n", val, _keyf->filename());
}
}
void KeyframeComponent::reset() {
active_ = false;
_active = false;
}
void KeyframeComponent::update() {
if (! active_)
if (!_active)
return;
if (currTime_ < 0) // For first time through
currTime_ = 0;
if (_currTime < 0) // For first time through
_currTime = 0;
else
currTime_ += Engine::instance()->frameTime();
int animLength = int(keyf_->length() * 1000);
if (currTime_ > animLength) { // What to do at end?
switch (repeatMode_) {
case 0: // Stop
case 3: // Fade at end
active_ = false;
return;
case 1: // Loop
do
currTime_ -= animLength;
while (currTime_ > animLength);
break;
case 2: // Hold at end
currTime_ = animLength;
break;
_currTime += Engine::instance()->frameTime();
int animLength = (int)(_keyf->length() * 1000);
if (_currTime > animLength) { // What to do at end?
switch (_repeatMode) {
case 0: // Stop
case 3: // Fade at end
_active = false;
return;
case 1: // Loop
do
_currTime -= animLength;
while (_currTime > animLength);
break;
case 2: // Hold at end
_currTime = animLength;
break;
}
}
keyf_->animate(hier_, currTime_ / 1000.0, priority1_, priority2_);
_keyf->animate(_hier, _currTime / 1000.0, _priority1, _priority2);
}
void KeyframeComponent::init() {
ModelComponent *mc = dynamic_cast<ModelComponent *>(parent_);
ModelComponent *mc = dynamic_cast<ModelComponent *>(_parent);
if (mc != NULL)
hier_ = mc->hierarchy();
_hier = mc->hierarchy();
else {
warning("Parent of %s was not a model\n", keyf_->filename());
hier_ = NULL;
warning("Parent of %s was not a model\n", _keyf->filename());
_hier = NULL;
}
}
MeshComponent::MeshComponent(Costume::Component *parent, int parentID, const char *name) :
Costume::Component(parent, parentID), node_(NULL) {
if (std::sscanf(name, "mesh %d", &num_) < 1)
Costume::Component(parent, parentID), _node(NULL) {
if (std::sscanf(name, "mesh %d", &_num) < 1)
error("Couldn't parse mesh name %s\n", name);
}
void MeshComponent::init() {
ModelComponent *mc = dynamic_cast<ModelComponent *>(parent_);
ModelComponent *mc = dynamic_cast<ModelComponent *>(_parent);
if (mc != NULL)
node_ = mc->hierarchy() + num_;
_node = mc->hierarchy() + _num;
else {
warning("Parent of mesh %d was not a model\n", num_);
node_ = NULL;
warning("Parent of mesh %d was not a model\n", _num);
_node = NULL;
}
}
void MeshComponent::setKey(int val) {
node_->meshVisible_ = (val != 0);
_node->_meshVisible = (val != 0);
}
void MeshComponent::reset() {
node_->meshVisible_ = true;
_node->_meshVisible = true;
}
void MeshComponent::update() {
node_->setMatrix( matrix_ );
node_->update();
_node->setMatrix(_matrix);
_node->update();
}
class MaterialComponent : public Costume::Component {
public:
MaterialComponent(Costume::Component *parent, int parentID,
const char *filename);
MaterialComponent(Costume::Component *parent, int parentID, const char *filename);
void init();
void setKey(int val);
void setupTexture();
@ -428,57 +422,54 @@ public:
~MaterialComponent() { }
private:
ResPtr<Material> mat_;
std::string filename_;
int num_;
ResPtr<Material> _mat;
std::string _filename;
int _num;
};
MaterialComponent::MaterialComponent(Costume::Component *parent, int parentID,
const char *filename) :
Costume::Component(parent, parentID), filename_(filename), num_(0) {
MaterialComponent::MaterialComponent(Costume::Component *parent, int parentID, const char *filename) :
Costume::Component(parent, parentID), _filename(filename), _num(0) {
warning("Constructing MaterialComponent %s\n", filename);
}
void MaterialComponent::init() {
warning("MaterialComponent::init on %s\n", filename_.c_str());
warning("MaterialComponent::init on %s\n", _filename.c_str());
// The parent model and thus all its textures should have been
// loaded by now, so passing an arbitrary colormap here
// shouldn't cause problems.
ResPtr<CMap> cmap =
ResourceLoader::instance()->loadColormap("item.cmp");
mat_ = ResourceLoader::instance()->loadMaterial(filename_.c_str(), *cmap);
ResPtr<CMap> cmap = ResourceLoader::instance()->loadColormap("item.cmp");
_mat = ResourceLoader::instance()->loadMaterial(_filename.c_str(), *cmap);
}
void MaterialComponent::setKey(int val) {
num_ = val;
_num = val;
}
void MaterialComponent::setupTexture() {
mat_->setNumber(num_);
_mat->setNumber(_num);
}
void MaterialComponent::reset() {
num_ = 0;
_num = 0;
}
class LuaVarComponent : public Costume::Component {
public:
LuaVarComponent(Costume::Component *parent, int parentID,
const char *name);
LuaVarComponent(Costume::Component *parent, int parentID, const char *name);
void setKey(int val);
~LuaVarComponent() { }
private:
std::string name_;
std::string _name;
};
LuaVarComponent::LuaVarComponent(Costume::Component *parent, int parentID, const char *name) :
Costume::Component(parent, parentID), name_(name) {
Costume::Component(parent, parentID), _name(name) {
}
void LuaVarComponent::setKey(int val) {
lua_pushnumber(val);
lua_setglobal(const_cast<char *>(name_.c_str()));
lua_setglobal(const_cast<char *>(_name.c_str()));
}
class SoundComponent : public Costume::Component {
@ -489,7 +480,7 @@ public:
~SoundComponent() { }
private:
ResPtr<Sound> sound_;
ResPtr<Sound> _sound;
};
SoundComponent::SoundComponent(Costume::Component *parent, int parentID, const char *filename) :
@ -497,33 +488,33 @@ SoundComponent::SoundComponent(Costume::Component *parent, int parentID, const c
const char *comma = std::strchr(filename, ',');
if (comma != NULL) {
std::string realName(filename, comma);
sound_ = ResourceLoader::instance()->loadSound(realName.c_str());
} else
sound_ = ResourceLoader::instance()->loadSound(filename);
_sound = ResourceLoader::instance()->loadSound(realName.c_str());
} else {
_sound = ResourceLoader::instance()->loadSound(filename);
}
}
void SoundComponent::setKey(int val) {
switch (val) {
case 0:
Mixer::instance()->playSfx(sound_);
Mixer::instance()->playSfx(_sound);
break;
case 2:
Mixer::instance()->stopSfx(sound_);
Mixer::instance()->stopSfx(_sound);
break;
default:
warning("Unknown key %d for sound %s\n", val, sound_->filename());
warning("Unknown key %d for sound %s\n", val, _sound->filename());
}
}
void SoundComponent::reset() {
Mixer::instance()->stopSfx(sound_);
Mixer::instance()->stopSfx(_sound);
}
Costume::Costume(const char *filename, const char *data, int len, Costume *prevCost) :
fname_(filename) {
_fname(filename) {
TextSplitter ts(data, len);
ts.expectString("costume v0.1");
ts.expectString("section tags");
int numTags;
ts.scanString(" numtags %d", 1, &numTags);
@ -537,9 +528,9 @@ Costume::Costume(const char *filename, const char *data, int len, Costume *prevC
}
ts.expectString("section components");
ts.scanString(" numcomponents %d", 1, &numComponents_);
components_ = new Component*[numComponents_];
for (int i = 0; i < numComponents_; i++) {
ts.scanString(" numcomponents %d", 1, &_numComponents);
_components = new Component *[_numComponents];
for (int i = 0; i < _numComponents; i++) {
int id, tagID, hash, parentID;
int namePos;
const char *line = ts.currentLine();
@ -549,148 +540,152 @@ Costume::Costume(const char *filename, const char *data, int len, Costume *prevC
// Check for sharing a main model with the previous costume
if (id == 0 && prevCost != NULL && std::memcmp(tags[tagID], "mmdl", 4) == 0) {
MainModelComponent *mmc = dynamic_cast<MainModelComponent *>(prevCost->components_[0]);
if (mmc != NULL && mmc->filename_ == std::string(line + namePos)) {
components_[id] = new MainModelComponent(line + namePos, mmc->obj_, mmc->hier_);
MainModelComponent *mmc = dynamic_cast<MainModelComponent *>(prevCost->_components[0]);
if (mmc != NULL && mmc->_filename == std::string(line + namePos)) {
_components[id] = new MainModelComponent(line + namePos, mmc->_obj, mmc->_hier);
continue;
}
}
components_[id] = loadComponent(tags[tagID],
parentID == -1 ? NULL : components_[parentID], parentID,
line + namePos);
_components[id] = loadComponent(tags[tagID], parentID == -1 ? NULL : _components[parentID], parentID, line + namePos);
}
delete[] tags;
for (int i = 0; i < numComponents_; i++)
if (components_[i] != NULL)
components_[i]->init();
for (int i = 0; i < _numComponents; i++)
if (_components[i] != NULL)
_components[i]->init();
ts.expectString("section chores");
ts.scanString(" numchores %d", 1, &numChores_);
chores_ = new Chore[numChores_];
for (int i = 0; i < numChores_; i++) {
ts.scanString(" numchores %d", 1, &_numChores);
_chores = new Chore[_numChores];
for (int i = 0; i < _numChores; i++) {
int id, length, tracks;
char name[32];
ts.scanString(" %d %d %d %32s", 4, &id, &length, &tracks, name);
chores_[id].length_ = length;
chores_[id].numTracks_ = tracks;
std::memcpy(chores_[id].name_, name, 32);
_chores[id]._length = length;
_chores[id]._numTracks = tracks;
std::memcpy(_chores[id]._name, name, 32);
printf("Loaded chore: %s\n", name);
}
ts.expectString("section keys");
for (int i = 0; i < numChores_; i++) {
for (int i = 0; i < _numChores; i++) {
int which;
ts.scanString("chore %d", 1, &which);
chores_[which].load(this, ts);
_chores[which].load(this, ts);
}
}
Costume::~Costume() {
stopChores();
for (int i = numComponents_ - 1; i >= 0; i--)
delete components_[i];
delete[] chores_;
for (int i = _numComponents - 1; i >= 0; i--)
delete _components[i];
delete[] _chores;
}
Costume::Component::Component(Component *parent, int parentID) {
parentID_ = parentID;
_parentID = parentID;
setParent(parent);
}
void Costume::Component::setParent(Component *newParent) {
parent_ = newParent;
child_ = NULL;
sibling_ = NULL;
if (parent_ != NULL) {
Component **lastChildPos = &parent_->child_;
_parent = newParent;
_child = NULL;
_sibling = NULL;
if (_parent != NULL) {
Component **lastChildPos = &_parent->_child;
while (*lastChildPos != NULL)
lastChildPos = &((*lastChildPos)->sibling_);
lastChildPos = &((*lastChildPos)->_sibling);
*lastChildPos = this;
}
}
void Costume::Chore::load(Costume *owner, TextSplitter &ts) {
owner_ = owner;
tracks_ = new ChoreTrack[numTracks_];
hasPlayed_ = playing_ = false;
for (int i = 0; i < numTracks_; i++) {
_owner = owner;
_tracks = new ChoreTrack[_numTracks];
_hasPlayed = _playing = false;
for (int i = 0; i < _numTracks; i++) {
int compID, numKeys;
ts.scanString(" %d %d", 2, &compID, &numKeys);
tracks_[i].compID_ = compID;
tracks_[i].numKeys_ = numKeys;
tracks_[i].keys_ = new TrackKey[numKeys];
for (int j = 0; j < numKeys; j++)
ts.scanString(" %d %d", 2, &tracks_[i].keys_[j].time_, &tracks_[i].keys_[j].value_);
_tracks[i]._compID = compID;
_tracks[i]._numKeys = numKeys;
_tracks[i]._keys = new TrackKey[numKeys];
for (int j = 0; j < numKeys; j++) {
ts.scanString(" %d %d", 2, &_tracks[i]._keys[j]._time, &_tracks[i]._keys[j]._value);
}
}
}
void Costume::Chore::play() {
playing_ = true;
hasPlayed_ = true;
looping_ = false;
currTime_ = -1;
_playing = true;
_hasPlayed = true;
_looping = false;
_currTime = -1;
}
void Costume::Chore::playLooping() {
playing_ = true;
hasPlayed_ = true;
looping_ = true;
currTime_ = -1;
_playing = true;
_hasPlayed = true;
_looping = true;
_currTime = -1;
}
void Costume::Chore::stop() {
if (! hasPlayed_)
if (!_hasPlayed)
return;
playing_ = false;
hasPlayed_ = false;
for (int i = 0; i < numTracks_; i++) {
Component *comp = owner_->components_[tracks_[i].compID_];
_playing = false;
_hasPlayed = false;
for (int i = 0; i < _numTracks; i++) {
Component *comp = _owner->_components[_tracks[i]._compID];
if (comp != NULL)
comp->reset();
}
}
void Costume::Chore::setKeys(int startTime, int stopTime) {
for (int i = 0; i < numTracks_; i++) {
Component *comp = owner_->components_[tracks_[i].compID_];
for (int i = 0; i < _numTracks; i++) {
Component *comp = _owner->_components[_tracks[i]._compID];
if (comp == NULL)
continue;
for (int j = 0; j < tracks_[i].numKeys_; j++) {
if (tracks_[i].keys_[j].time_ > stopTime)
for (int j = 0; j < _tracks[i]._numKeys; j++) {
if (_tracks[i]._keys[j]._time > stopTime)
break;
if (tracks_[i].keys_[j].time_ > startTime)
comp->setKey(tracks_[i].keys_[j].value_);
if (_tracks[i]._keys[j]._time > startTime)
comp->setKey(_tracks[i]._keys[j]._value);
}
}
}
void Costume::Chore::update() {
if (! playing_)
if (!_playing)
return;
int newTime;
if (currTime_ < 0)
if (_currTime < 0)
newTime = 0; // For first time through
else
newTime = currTime_ + Engine::instance()->frameTime();
setKeys(currTime_, newTime);
if (newTime > length_) {
if (! looping_)
playing_ = false;
else {
newTime = _currTime + Engine::instance()->frameTime();
setKeys(_currTime, newTime);
if (newTime > _length) {
if (!_looping) {
_playing = false;
} else {
do {
newTime -= length_;
newTime -= _length;
setKeys(-1, newTime);
} while (newTime > length_);
} while (newTime > _length);
}
}
currTime_ = newTime;
_currTime = newTime;
}
Costume::Component *Costume::loadComponent
(char tag[4], Costume::Component *parent, int parentID, const char *name) {
Costume::Component *Costume::loadComponent (char tag[4], Costume::Component *parent, int parentID, const char *name) {
if (std::memcmp(tag, "mmdl", 4) == 0)
return new MainModelComponent(parent, parentID, name);
else if (std::memcmp(tag, "modl", 4) == 0)
@ -709,63 +704,65 @@ Costume::Component *Costume::loadComponent
return new BitmapComponent(parent, parentID, name);
else if (std::memcmp(tag, "mat ", 4) == 0)
return new MaterialComponent(parent, parentID, name);
warning("Unknown tag '%.4s', name '%s'\n", tag, name);
return NULL;
}
void Costume::stopChores() {
for (int i = 0; i < numChores_; i++)
chores_[i].stop();
for (int i = 0; i < _numChores; i++)
_chores[i].stop();
}
int Costume::isChoring(int num, bool excludeLooping) {
if (chores_[num].playing_ && !(excludeLooping && chores_[num].looping_))
if (_chores[num]._playing && !(excludeLooping && _chores[num]._looping))
return num;
else
return -1;
}
int Costume::isChoring(bool excludeLooping) {
for (int i = 0; i < numChores_; i++) {
if (chores_[i].playing_ && !(excludeLooping && chores_[i].looping_))
for (int i = 0; i < _numChores; i++) {
if (_chores[i]._playing && !(excludeLooping && _chores[i]._looping))
return i;
}
return -1;
}
void Costume::setupTextures() {
for (int i = 0; i < numComponents_; i++)
if (components_[i] != NULL)
components_[i]->setupTexture();
for (int i = 0; i < _numComponents; i++)
if (_components[i] != NULL)
_components[i]->setupTexture();
}
void Costume::draw() {
for (int i = 0; i < numComponents_; i++)
if (components_[i] != NULL)
components_[i]->draw();
for (int i = 0; i < _numComponents; i++)
if (_components[i] != NULL)
_components[i]->draw();
}
void Costume::update() {
for (int i = 0; i < numChores_; i++)
chores_[i].update();
for (int i = 0; i < numComponents_; i++) {
if (components_[i] != NULL) {
components_[i]->setMatrix( matrix_ );
components_[i]->update();
for (int i = 0; i < _numChores; i++)
_chores[i].update();
for (int i = 0; i < _numComponents; i++) {
if (_components[i] != NULL) {
_components[i]->setMatrix(_matrix);
_components[i]->update();
}
}
}
void Costume::setHead( int joint1, int joint2, int joint3, float maxRoll, float maxPitch, float maxYaw ) {
head_.joint1 = joint1;
head_.joint2 = joint2;
head_.joint3 = joint3;
head_.maxRoll = maxRoll;
head_.maxPitch = maxPitch;
head_.maxYaw = maxYaw;
void Costume::setHead(int joint1, int joint2, int joint3, float maxRoll, float maxPitch, float maxYaw) {
_head._joint1 = joint1;
_head._joint2 = joint2;
_head._joint3 = joint3;
_head._maxRoll = maxRoll;
_head._maxPitch = maxPitch;
_head._maxYaw = maxYaw;
}
void Costume::setPosRotate( Vector3d pos_, float pitch_, float yaw_, float roll_ ) {
matrix_.pos_ = pos_;
matrix_.rot_.buildFromPitchYawRoll( pitch_, yaw_, roll_ );
void Costume::setPosRotate(Vector3d pos, float pitch, float yaw, float roll) {
_matrix._pos = pos;
_matrix._rot.buildFromPitchYawRoll(pitch, yaw, roll);
}

View File

@ -30,28 +30,28 @@ public:
~Costume();
const char *filename() const { return fname_.c_str(); }
const char *filename() const { return _fname.c_str(); }
void playChore(int num) { chores_[num].play(); }
void playChoreLooping(int num) { chores_[num].playLooping(); }
void setChoreLooping(int num, bool val) { chores_[num].setLooping(val); }
void stopChore(int num) { chores_[num].stop(); }
void playChore(int num) { _chores[num].play(); }
void playChoreLooping(int num) { _chores[num].playLooping(); }
void setChoreLooping(int num, bool val) { _chores[num].setLooping(val); }
void stopChore(int num) { _chores[num].stop(); }
void stopChores();
int isChoring(int num, bool excludeLooping);
int isChoring(bool excludeLooping);
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 setupTextures();
void draw();
void setPosRotate( Vector3d pos_, float pitch_, float yaw_, float roll_ );
void setPosRotate(Vector3d pos, float pitch, float yaw, float roll);
class Component {
public:
Component(Component *parent, int parentID);
virtual void setMatrix( Matrix4 matrix ) { };
virtual void setMatrix(Matrix4 matrix) { };
virtual void init() { }
virtual void setKey(int /* val */) { }
virtual void update() { }
@ -61,9 +61,9 @@ public:
virtual ~Component() { }
protected:
int parentID_;
Component *parent_, *child_, *sibling_;
Matrix4 matrix_;
int _parentID;
Component *_parent, *_child, *_sibling;
Matrix4 _matrix;
void setParent(Component *newParent);
friend class Costume;
@ -72,58 +72,58 @@ public:
private:
Component *loadComponent(char tag[4], Component *parent, int parentID, const char *name);
std::string fname_;
std::string _fname;
int numComponents_;
Component **components_;
int _numComponents;
Component **_components;
struct TrackKey {
int time_, value_;
int _time, _value;
};
struct ChoreTrack {
int compID_;
int numKeys_;
TrackKey *keys_;
int _compID;
int _numKeys;
TrackKey *_keys;
};
struct Head {
int joint1;
int joint2;
int joint3;
float maxRoll;
float maxPitch;
float maxYaw;
} head_;
int _joint1;
int _joint2;
int _joint3;
float _maxRoll;
float _maxPitch;
float _maxYaw;
} _head;
class Chore {
public:
void load(Costume *owner, TextSplitter &ts);
void play();
void playLooping();
void setLooping(bool val) { looping_ = val; }
void setLooping(bool val) { _looping = val; }
void stop();
void update();
private:
Costume *owner_;
Costume *_owner;
int length_;
int numTracks_;
ChoreTrack *tracks_;
char name_[32];
int _length;
int _numTracks;
ChoreTrack *_tracks;
char _name[32];
bool hasPlayed_, playing_, looping_;
int currTime_;
bool _hasPlayed, _playing, _looping;
int _currTime;
void setKeys(int startTime, int stopTime);
friend class Costume;
};
int numChores_;
Chore *chores_;
Matrix4 matrix_;
int _numChores;
Chore *_chores;
Matrix4 _matrix;
};
#endif

View File

@ -37,6 +37,7 @@ void hexdump(const byte * data, int len, int bytesPerLine) {
int i;
byte c;
int offset = 0;
while (len >= bytesPerLine) {
printf("%06x: ", offset);
for (i = 0; i < bytesPerLine; i++) {

View File

@ -122,57 +122,56 @@ void Driver::drawModel(const Model::Mesh *model) {
GLdouble projection[500];
GLint viewPort[500];
glGetDoublev( GL_MODELVIEW_MATRIX, modelView );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewPort);
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetIntegerv(GL_VIEWPORT, viewPort);
glDisable(GL_DEPTH_TEST);
glPointSize( 3.f );
glColor4f( 1.f, 0.f, 0.f, 1.f );
glPointSize(3.f);
glColor4f(1.f, 0.f, 0.f, 1.f);
glDisable(GL_TEXTURE_2D );
glBegin( GL_POINTS );
glVertex3f( matrix_.pos_.x(), matrix_.pos_.y(), matrix_.pos_.z() );
glBegin(GL_POINTS);
glVertex3f(_matrix._pos.x(), _matrix._pos.y(), _matrix._pos.z());
glEnd();
glEnable(GL_DEPTH_TEST);
glPopMatrix();
glEnable(GL_TEXTURE_2D );*/
glEnable(GL_TEXTURE_2D);*/
// Yaz: debug
// this draw the poly points
/*glPushMatrix();
glLoadIdentity();
glPointSize( 3.f );
glColor4f( 0.f, 1.f, 0.f, 1.f );
glDisable(GL_TEXTURE_2D );
glPointSize(3.f);
glColor4f(0.f, 1.f, 0.f, 1.f);
glDisable(GL_TEXTURE_2D);
{
GLdouble modelView[500];
GLdouble projection[500];
GLint viewPort[500];
glGetDoublev( GL_MODELVIEW_MATRIX, modelView );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewPort);
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetIntegerv(GL_VIEWPORT, viewPort);
}
glBegin( GL_POINTS );
for (int i = 0; i < numFaces_; i++) {
for (int i = 0; i < _numFaces; i++) {
Vector3d v;
Matrix4 tempMatrix = matrix_;
Matrix4 tempMatrix = _matrix;
float* pVertices;
int j;
for( j =0; j< faces_[i].numVertices_; j++ ) {
pVertices = vertices_ + 3 * faces_[i].vertices_[j];
v.set( *(pVertices), *(pVertices+1), *(pVertices+2) );
v.set(*(pVertices), *(pVertices + 1), *(pVertices + 2));
tempMatrix.rot_.transform( &v );
v+= tempMatrix.pos_;
glVertex3f( v.x(), v.y(), v.z() );
tempMatrix._rot.transform(&v);
v += tempMatrix._pos;
glVertex3f(v.x(), v.y(), v.z());
}
}
@ -184,7 +183,7 @@ void Driver::drawModel(const Model::Mesh *model) {
// Ender: HACK HACK HACK
// Mannys head isn't computed correctly, so bail out to prevent memory corruption.
// at least until it IS computed, or the DirtyScreen code has bounds checking :)
//if (strstr(name_, "m_head_1"))
//if (strstr(_name, "m_head_1"))
// return;
// Yaz: debug
@ -197,14 +196,14 @@ void Driver::drawModel(const Model::Mesh *model) {
GLdouble left = 1000;
GLdouble bottom = -1000;
for (int i = 0; i < model->numFaces_; i++) {
for (int i = 0; i < model->_numFaces; i++) {
Vector3d v;
Matrix4 tempMatrix = model->matrix_;
Matrix4 tempMatrix = model->_matrix;
float* pVertices;
int j;
float bestDepth = 0;
for(j = 0; j < model->faces_[i].numVertices_; j++) {
for (j = 0; j < model->_faces[i]._numVertices; j++) {
GLdouble modelView[500];
GLdouble projection[500];
GLint viewPort[500];
@ -213,12 +212,12 @@ void Driver::drawModel(const Model::Mesh *model) {
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetIntegerv(GL_VIEWPORT, viewPort);
pVertices = model->vertices_ + 3 * model->faces_[i].vertices_[j];
pVertices = model->_vertices + 3 * model->_faces[i]._vertices[j];
v.set(*(pVertices), *(pVertices + 1), *(pVertices + 2));
tempMatrix.rot_.transform(&v);
v+= tempMatrix.pos_;
tempMatrix._rot.transform(&v);
v += tempMatrix._pos;
GLdouble winX;
GLdouble winY;
@ -226,16 +225,16 @@ void Driver::drawModel(const Model::Mesh *model) {
gluProject(v.x(), v.y(), v.z(), modelView, projection, viewPort, &winX, &winY, &winZ);
if(winX > right)
if (winX > right)
right = winX;
if(winX < left)
if (winX < left)
left = winX;
if(winY < top)
if (winY < top)
top = winY;
if(winY > bottom)
if (winY > bottom)
bottom = winY;
if(winZ > bestDepth )
if (winZ > bestDepth )
bestDepth = winZ;
}
@ -244,9 +243,9 @@ void Driver::drawModel(const Model::Mesh *model) {
}
/*
glDisable(GL_DEPTH_TEST);
glPointSize( 3.f );
glColor4f( 1.f, 1.f, 0.f, 1.f );
glDisable(GL_TEXTURE_2D );
glPointSize(3.f);
glColor4f(1.f, 1.f, 0.f, 1.f);
glDisable(GL_TEXTURE_2D);
glBegin(GL_LINES);
@ -255,32 +254,32 @@ void Driver::drawModel(const Model::Mesh *model) {
GLdouble objz;
// top
gluUnProject( left, top, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
glVertex3f( objx, objy, objz );
gluUnProject( right, top, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
glVertex3f( objx, objy, objz );
gluUnProject(left, top, 1.f, modelView, projection, viewPort, &objx, &objy, &objz);
glVertex3f(objx, objy, objz);
gluUnProject(right, top, 1.f, modelView, projection, viewPort, &objx, &objy, &objz);
glVertex3f(objx, objy, objz);
// bottom
gluUnProject( left, bottom, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
glVertex3f( objx, objy, objz );
gluUnProject( right, bottom, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
glVertex3f( objx, objy, objz );
gluUnProject(left, bottom, 1.f, modelView, projection, viewPort, &objx, &objy, &objz);
glVertex3f(objx, objy, objz);
gluUnProject(right, bottom, 1.f, modelView, projection, viewPort, &objx, &objy, &objz);
glVertex3f(objx, objy, objz);
// left
gluUnProject( left, top, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
glVertex3f( objx, objy, objz );
gluUnProject( left, bottom, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
glVertex3f( objx, objy, objz );
gluUnProject(left, top, 1.f, modelView, projection, viewPort, &objx, &objy, &objz);
glVertex3f(objx, objy, objz);
gluUnProject(left, bottom, 1.f, modelView, projection, viewPort, &objx, &objy, &objz);
glVertex3f(objx, objy, objz);
// right
gluUnProject( right, top, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
glVertex3f( objx, objy, objz );
gluUnProject( right, bottom, 1.f, modelView, projection, viewPort, &objx, &objy, &objz );
glVertex3f( objx, objy, objz );
gluUnProject(right, top, 1.f, modelView, projection, viewPort, &objx, &objy, &objz);
glVertex3f(objx, objy, objz);
gluUnProject(right, bottom, 1.f, modelView, projection, viewPort, &objx, &objy, &objz);
glVertex3f(objx, objy, objz);
glEnd();
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D );
glEnable(GL_TEXTURE_2D);
*/
glPopMatrix();
}
@ -299,20 +298,20 @@ void Driver::updateMesh(const Model::Mesh *mesh) {
GLdouble left = 1000;
GLdouble bottom = -1000;
for (int i = 0; i < mesh->numFaces_; i++) {
for (int i = 0; i < mesh->_numFaces; i++) {
Vector3d v;
Matrix4 tempMatrix = mesh->matrix_;
Matrix4 tempMatrix = mesh->_matrix;
float *pVertices;
int j;
float bestDepth = 0;
for (j = 0; j < mesh->faces_[i].numVertices_; j++) {
pVertices = mesh->vertices_ + 3 * mesh->faces_[i].vertices_[j];
for (j = 0; j < mesh->_faces[i]._numVertices; j++) {
pVertices = mesh->_vertices + 3 * mesh->_faces[i]._vertices[j];
v.set(*(pVertices), *(pVertices + 1), *(pVertices + 2));
tempMatrix.rot_.transform(&v);
v+= tempMatrix.pos_;
tempMatrix._rot.transform(&v);
v += tempMatrix._pos;
GLdouble winX;
GLdouble winY;
@ -344,67 +343,67 @@ void Driver::updateMesh(const Model::Mesh *mesh) {
}
void Driver::drawModelFace(const Model::Face *face, float *vertices, float *vertNormals, float *textureVerts) {
glNormal3fv(face->normal_.coords_);
glNormal3fv(face->_normal._coords);
glBegin(GL_POLYGON);
for (int i = 0; i < face->numVertices_; i++) {
glNormal3fv(vertNormals + 3 * face->vertices_[i]);
if (face->texVertices_ != NULL)
glTexCoord2fv(textureVerts + 2 * face->texVertices_[i]);
glVertex3fv(vertices + 3 * face->vertices_[i]);
for (int i = 0; i < face->_numVertices; i++) {
glNormal3fv(vertNormals + 3 * face->_vertices[i]);
if (face->_texVertices != NULL)
glTexCoord2fv(textureVerts + 2 * face->_texVertices[i]);
glVertex3fv(vertices + 3 * face->_vertices[i]);
}
glEnd();
}
void Driver::drawHierachyNode(const Model::HierNode *node) {
if (node->hierVisible_) {
if (node->_hierVisible) {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(node->animPos_.x() / node->totalWeight_, node->animPos_.y() / node->totalWeight_, node->animPos_.z() / node->totalWeight_);
glRotatef(node->animYaw_ / node->totalWeight_, 0, 0, 1);
glRotatef(node->animPitch_ / node->totalWeight_, 1, 0, 0);
glRotatef(node->animRoll_ / node->totalWeight_, 0, 1, 0);
glTranslatef(node->_animPos.x() / node->_totalWeight, node->_animPos.y() / node->_totalWeight, node->_animPos.z() / node->_totalWeight);
glRotatef(node->_animYaw / node->_totalWeight, 0, 0, 1);
glRotatef(node->_animPitch / node->_totalWeight, 1, 0, 0);
glRotatef(node->_animRoll / node->_totalWeight, 0, 1, 0);
if (node->mesh_ != NULL && node->meshVisible_) {
if (node->_mesh != NULL && node->_meshVisible) {
glPushMatrix();
glTranslatef(node->pivot_.x(), node->pivot_.y(), node->pivot_.z());
node->mesh_->draw();
glTranslatef(node->_pivot.x(), node->_pivot.y(), node->_pivot.z());
node->_mesh->draw();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
if (node->child_ != NULL) {
node->child_->draw();
if (node->_child != NULL) {
node->_child->draw();
glMatrixMode(GL_MODELVIEW);
}
glPopMatrix();
}
if (node->sibling_ != NULL)
node->sibling_->draw();
if (node->_sibling != NULL)
node->_sibling->draw();
}
void Driver::updateHierachyNode(const Model::HierNode *node) {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(node->animPos_.x() / node->totalWeight_, node->animPos_.y() / node->totalWeight_, node->animPos_.z() / node->totalWeight_);
glRotatef(node->animYaw_ / node->totalWeight_, 0, 0, 1);
glRotatef(node->animPitch_ / node->totalWeight_, 1, 0, 0);
glRotatef(node->animRoll_ / node->totalWeight_, 0, 1, 0);
glTranslatef(node->_animPos.x() / node->_totalWeight, node->_animPos.y() / node->_totalWeight, node->_animPos.z() / node->_totalWeight);
glRotatef(node->_animYaw / node->_totalWeight, 0, 0, 1);
glRotatef(node->_animPitch / node->_totalWeight, 1, 0, 0);
glRotatef(node->_animRoll / node->_totalWeight, 0, 1, 0);
if (node->mesh_ != NULL) {
if (node->_mesh != NULL) {
glPushMatrix();
glTranslatef(node->pivot_.x(), node->pivot_.y(), node->pivot_.z());
node->mesh_->matrix_ = node->pivotMatrix;
node->mesh_->update();
glTranslatef(node->_pivot.x(), node->_pivot.y(), node->_pivot.z());
node->_mesh->_matrix = node->_pivotMatrix;
node->_mesh->update();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
if (node->child_ != NULL ) {
node->child_->setMatrix(node->matrix_);
node->child_->update();
if (node->_child != NULL ) {
node->_child->setMatrix(node->_matrix);
node->_child->update();
glMatrixMode(GL_MODELVIEW);
}
@ -412,20 +411,20 @@ void Driver::updateHierachyNode(const Model::HierNode *node) {
}
void Driver::createBitmap(Bitmap *bitmap) {
if (bitmap->format_ == 1) {
bitmap->hasTransparency_ = false;
bitmap->num_tex_ = ((bitmap->width_ + (BITMAP_TEXTURE_SIZE - 1)) / BITMAP_TEXTURE_SIZE) *
((bitmap->height_ + (BITMAP_TEXTURE_SIZE - 1)) / BITMAP_TEXTURE_SIZE);
bitmap->tex_ids_ = new GLuint[bitmap->num_tex_ * bitmap->num_images_];
glGenTextures(bitmap->num_tex_ * bitmap->num_images_, bitmap->tex_ids_);
if (bitmap->_format == 1) {
bitmap->_hasTransparency = false;
bitmap->_num_tex = ((bitmap->_width + (BITMAP_TEXTURE_SIZE - 1)) / BITMAP_TEXTURE_SIZE) *
((bitmap->_height + (BITMAP_TEXTURE_SIZE - 1)) / BITMAP_TEXTURE_SIZE);
bitmap->_tex_ids = new GLuint[bitmap->_num_tex * bitmap->_num_images];
glGenTextures(bitmap->_num_tex * bitmap->_num_images, bitmap->_tex_ids);
char *texData = new char[4 * bitmap->width_ * bitmap->height_];
byte *texData = new byte[4 * bitmap->_width * bitmap->_height];
for (int pic = 0; pic < bitmap->num_images_; pic++) {
for (int pic = 0; pic < bitmap->_num_images; pic++) {
// Convert data to 32-bit RGBA format
char *texDataPtr = texData;
uint16 *bitmapData = reinterpret_cast<uint16 *>(bitmap->data_[pic]);
for (int i = 0; i < bitmap->width_ * bitmap->height_; i++, texDataPtr += 4, bitmapData++) {
byte *texDataPtr = texData;
uint16 *bitmapData = reinterpret_cast<uint16 *>(bitmap->_data[pic]);
for (int i = 0; i < bitmap->_width * bitmap->_height; i++, texDataPtr += 4, bitmapData++) {
uint16 pixel = *bitmapData;
int r = pixel >> 11;
texDataPtr[0] = (r << 3) | (r >> 2);
@ -435,40 +434,33 @@ void Driver::createBitmap(Bitmap *bitmap) {
texDataPtr[2] = (b << 3) | (b >> 2);
if (pixel == 0xf81f) { // transparent
texDataPtr[3] = 0;
bitmap->hasTransparency_ = true;
bitmap->_hasTransparency = true;
} else {
texDataPtr[3] = 255;
}
}
for (int i = 0; i < bitmap->num_tex_; i++) {
glBindTexture(GL_TEXTURE_2D, bitmap->tex_ids_[bitmap->num_tex_ * pic + i]);
for (int i = 0; i < bitmap->_num_tex; i++) {
glBindTexture(GL_TEXTURE_2D, bitmap->_tex_ids[bitmap->_num_tex * pic + i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
BITMAP_TEXTURE_SIZE, BITMAP_TEXTURE_SIZE, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, BITMAP_TEXTURE_SIZE, BITMAP_TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap->width_);
glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap->_width);
int cur_tex_idx = bitmap->num_tex_ * pic;
int cur_tex_idx = bitmap->_num_tex * pic;
for (int y = 0; y < bitmap->height_; y += BITMAP_TEXTURE_SIZE) {
for (int x = 0; x < bitmap->width_; x += BITMAP_TEXTURE_SIZE) {
int width = (x + BITMAP_TEXTURE_SIZE >= bitmap->width_) ? (bitmap->width_ - x) : BITMAP_TEXTURE_SIZE;
int height = (y + BITMAP_TEXTURE_SIZE >= bitmap->height_) ? (bitmap->height_ - y) : BITMAP_TEXTURE_SIZE;
glBindTexture(GL_TEXTURE_2D, bitmap->tex_ids_[cur_tex_idx]);
glTexSubImage2D(GL_TEXTURE_2D,
0,
0, 0,
width, height,
GL_RGBA,
GL_UNSIGNED_BYTE,
texData + (y * 4 * bitmap->width_) + (4 * x));
for (int y = 0; y < bitmap->_height; y += BITMAP_TEXTURE_SIZE) {
for (int x = 0; x < bitmap->_width; x += BITMAP_TEXTURE_SIZE) {
int width = (x + BITMAP_TEXTURE_SIZE >= bitmap->_width) ? (bitmap->_width - x) : BITMAP_TEXTURE_SIZE;
int height = (y + BITMAP_TEXTURE_SIZE >= bitmap->_height) ? (bitmap->_height - y) : BITMAP_TEXTURE_SIZE;
glBindTexture(GL_TEXTURE_2D, bitmap->_tex_ids[cur_tex_idx]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
texData + (y * 4 * bitmap->_width) + (4 * x));
cur_tex_idx++;
}
}
@ -478,25 +470,25 @@ void Driver::createBitmap(Bitmap *bitmap) {
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
delete [] texData;
} else {
for (int pic = 0; pic < bitmap->num_images_; pic++) {
uint16 *zbufPtr = reinterpret_cast<uint16 *>(bitmap->data_[pic]);
for (int i = 0; i < (bitmap->width_ * bitmap->height_); i++) {
uint16 val = READ_LE_UINT16(bitmap->data_[pic] + 2 * i);
for (int pic = 0; pic < bitmap->_num_images; pic++) {
uint16 *zbufPtr = reinterpret_cast<uint16 *>(bitmap->_data[pic]);
for (int i = 0; i < (bitmap->_width * bitmap->_height); i++) {
uint16 val = READ_LE_UINT16(bitmap->_data[pic] + 2 * i);
zbufPtr[i] = 0xffff - ((uint32) val) * 0x10000 / 100 / (0x10000 - val);
}
// Flip the zbuffer image to match what GL expects
for (int y = 0; y < bitmap->height_ / 2; y++) {
uint16 *ptr1 = zbufPtr + y * bitmap->width_;
uint16 *ptr2 = zbufPtr + (bitmap->height_ - 1 - y) * bitmap->width_;
for (int x = 0; x < bitmap->width_; x++, ptr1++, ptr2++) {
for (int y = 0; y < bitmap->_height / 2; y++) {
uint16 *ptr1 = zbufPtr + y * bitmap->_width;
uint16 *ptr2 = zbufPtr + (bitmap->_height - 1 - y) * bitmap->_width;
for (int x = 0; x < bitmap->_width; x++, ptr1++, ptr2++) {
uint16 tmp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = tmp;
}
}
}
bitmap->tex_ids_ = NULL;
bitmap->_tex_ids = NULL;
}
}
@ -510,23 +502,22 @@ void Driver::drawBitmap(const Bitmap *bitmap) {
glLoadIdentity();
// A lot more may need to be put there : disabling Alpha test, blending, ...
// For now, just keep this here :-)
if (bitmap->format_ == 1 && bitmap->hasTransparency_) {
if (bitmap->_format == 1 && bitmap->_hasTransparency) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else
} else
glDisable(GL_BLEND);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
if (bitmap->format_ == 1) { // Normal image
if (bitmap->_format == 1) { // Normal image
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_SCISSOR_TEST);
glScissor(bitmap->x_, 480 - (bitmap->y_ + bitmap->height_), bitmap->width_, bitmap->height_);
int cur_tex_idx = bitmap->num_tex_ * (bitmap->curr_image_ - 1);
for (int y = bitmap->y_; y < (bitmap->y_ + bitmap->height_); y += BITMAP_TEXTURE_SIZE) {
for (int x = bitmap->x_; x < (bitmap->x_ + bitmap->width_); x += BITMAP_TEXTURE_SIZE) {
glBindTexture(GL_TEXTURE_2D, bitmap->tex_ids_[cur_tex_idx]);
glScissor(bitmap->_x, 480 - (bitmap->_y + bitmap->_height), bitmap->_width, bitmap->_height);
int cur_tex_idx = bitmap->_num_tex * (bitmap->_curr_image - 1);
for (int y = bitmap->_y; y < (bitmap->_y + bitmap->_height); y += BITMAP_TEXTURE_SIZE) {
for (int x = bitmap->_x; x < (bitmap->_x + bitmap->_width); x += BITMAP_TEXTURE_SIZE) {
glBindTexture(GL_TEXTURE_2D, bitmap->_tex_ids[cur_tex_idx]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2i(x, y);
@ -546,63 +537,63 @@ void Driver::drawBitmap(const Bitmap *bitmap) {
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
} else if (bitmap->format_ == 5) { // ZBuffer image
} else if (bitmap->_format == 5) { // ZBuffer image
// Only draw the manual zbuffer when we are not using screenblocks, and when enabled
if ((!ZBUFFER_GLOBAL) || SCREENBLOCKS_GLOBAL)
return;
g_driver->drawDepthBitmap(bitmap->x_, bitmap->y_, bitmap->width_, bitmap->height_, bitmap->data_[bitmap->curr_image_ - 1]);
g_driver->drawDepthBitmap(bitmap->_x, bitmap->_y, bitmap->_width, bitmap->_height, bitmap->_data[bitmap->_curr_image - 1]);
}
}
void Driver::destroyBitmap(Bitmap *bitmap) {
if (bitmap->tex_ids_) {
glDeleteTextures(bitmap->num_tex_ * bitmap->num_images_, bitmap->tex_ids_);
delete[] bitmap->tex_ids_;
if (bitmap->_tex_ids) {
glDeleteTextures(bitmap->_num_tex * bitmap->_num_images, bitmap->_tex_ids);
delete[] bitmap->_tex_ids;
}
}
void Driver::createMaterial(Material *material, const char *data, const CMap *cmap) {
material->textures_ = new GLuint[material->num_images_];
glGenTextures(material->num_images_, material->textures_);
char *texdata = new char[material->width_ * material->height_ * 4];
for (int i = 0; i < material->num_images_; i++) {
material->_textures = new GLuint[material->_num_images];
glGenTextures(material->_num_images, material->_textures);
char *texdata = new char[material->_width * material->_height * 4];
for (int i = 0; i < material->_num_images; i++) {
char *texdatapos = texdata;
for (int y = 0; y < material->height_; y++) {
for (int x = 0; x < material->width_; x++) {
for (int y = 0; y < material->_height; y++) {
for (int x = 0; x < material->_width; x++) {
int col = *(uint8 *)(data);
if (col == 0)
memset(texdatapos, 0, 4); // transparent
else {
memcpy(texdatapos, cmap->colors + 3 * *(uint8 *)(data), 3);
memcpy(texdatapos, cmap->_colors + 3 * (*(uint8 *)(data)), 3);
texdatapos[3] = '\xff'; // fully opaque
}
texdatapos += 4;
data++;
}
}
glBindTexture(GL_TEXTURE_2D, material->textures_[i]);
glBindTexture(GL_TEXTURE_2D, material->_textures[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, material->width_, material->height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, texdata);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, material->_width, material->_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texdata);
data += 24;
}
delete[] texdata;
}
void Driver::selectMaterial(const Material *material) {
glBindTexture(GL_TEXTURE_2D, material->textures_[material->curr_image_]);
glBindTexture(GL_TEXTURE_2D, material->_textures[material->_curr_image]);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glScalef(1.0f / material->width_, 1.0f / material->height_, 1);
glScalef(1.0f / material->_width, 1.0f / material->_height, 1);
}
void Driver::destroyMaterial(Material *material) {
glDeleteTextures(material->num_images_, material->textures_);
delete[] material->textures_;
glDeleteTextures(material->_num_images, material->_textures);
delete[] material->_textures;
}
void Driver::drawDepthBitmap(int x, int y, int w, int h, char *data) {
@ -620,13 +611,13 @@ void Driver::drawDepthBitmap(int x, int y, int w, int h, char *data) {
//Use this workaround for now.
#ifdef MACOSX
glBegin(GL_POINTS); glEnd();
glBegin(GL_POINTS);
glEnd();
#endif
glRasterPos2i(x, 479);
glBitmap(0, 0, 0, 0, 0, -1, NULL);
}
else
} else
glRasterPos2i(x, y + h);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
@ -660,9 +651,7 @@ void Driver::prepareSmushFrame(int width, int height, byte *bitmap) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
BITMAP_TEXTURE_SIZE, BITMAP_TEXTURE_SIZE, 0,
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BITMAP_TEXTURE_SIZE, BITMAP_TEXTURE_SIZE, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
@ -674,13 +663,7 @@ void Driver::prepareSmushFrame(int width, int height, byte *bitmap) {
int t_width = (x + BITMAP_TEXTURE_SIZE >= width) ? (width - x) : BITMAP_TEXTURE_SIZE;
int t_height = (y + BITMAP_TEXTURE_SIZE >= height) ? (height - y) : BITMAP_TEXTURE_SIZE;
glBindTexture(GL_TEXTURE_2D, _smushTexIds[curTexIdx]);
glTexSubImage2D(GL_TEXTURE_2D,
0,
0, 0,
t_width, t_height,
GL_RGB,
GL_UNSIGNED_SHORT_5_6_5,
bitmap + (y * 2 * width) + (2 * x));
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, t_width, t_height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, bitmap + (y * 2 * width) + (2 * x));
curTexIdx++;
}
}
@ -740,12 +723,11 @@ void Driver::drawSmushFrame(int offsetX, int offsetY) {
// Load emergency font
void Driver::loadEmergFont() {
int i;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
emergFont = glGenLists(128);
for (i = 32; i < 127; i++) {
glNewList(emergFont + i, GL_COMPILE);
_emergFont = glGenLists(128);
for (int i = 32; i < 127; i++) {
glNewList(_emergFont + i, GL_COMPILE);
glBitmap(8, 13, 0, 2, 10, 0, font[i - 32]);
glEndList();
}
@ -765,7 +747,7 @@ void Driver::drawEmergString(int x, int y, const char *text, const Color &fgColo
glColor3f(fgColor.red(), fgColor.green(), fgColor.blue());
glRasterPos2i(x, y);
glListBase(emergFont);
glListBase(_emergFont);
//glCallLists(strlen(strrchr(text, '/')) - 1, GL_UNSIGNED_BYTE, strrchr(text, '/') + 1);
glCallLists(strlen(text), GL_UNSIGNED_BYTE, (GLubyte *) text);

View File

@ -70,7 +70,7 @@ public:
void drawSmushFrame(int offsetX, int offsetY);
private:
GLuint emergFont;
GLuint _emergFont;
int _smushNumTex;
GLuint *_smushTexIds;
int _smushWidth;

View File

@ -30,19 +30,19 @@
#include "driver_gl.h"
Engine *Engine::instance_ = NULL;
Engine *Engine::_instance = NULL;
Engine::Engine() :
currScene_(NULL), selectedActor_(NULL) {
_currScene(NULL), _selectedActor(NULL) {
for (int i = 0; i < SDLK_EXTRA_LAST; i++)
controlsEnabled_[i] = false;
_controlsEnabled[i] = false;
_speechMode = 2;
}
void Engine::mainLoop() {
movieTime_ = 0;
frameTime_ = 0;
frameStart_ = SDL_GetTicks();
_movieTime = 0;
_frameTime = 0;
_frameStart = SDL_GetTicks();
unsigned int frameCounter = 0;
unsigned int timeAccum = 0;
unsigned int frameTimeCollection = 0;
@ -51,12 +51,11 @@ void Engine::mainLoop() {
_savegameSaveRequest = false;
_savegameFileName = NULL;
for (;;) {
// Process events
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_KEYDOWN && controlsEnabled_[event.key.keysym.sym]) {
if (event.type == SDL_KEYDOWN && _controlsEnabled[event.key.keysym.sym]) {
lua_beginblock();
lua_Object handler = getEventHandler("buttonHandler");
if (handler != LUA_NOOBJECT) {
@ -67,7 +66,7 @@ void Engine::mainLoop() {
}
lua_endblock();
}
if (event.type == SDL_KEYUP && controlsEnabled_[event.key.keysym.sym]) {
if (event.type == SDL_KEYUP && _controlsEnabled[event.key.keysym.sym]) {
// temporary hack for save/load request until game menu will work
if (event.key.keysym.sym == SDLK_F5) {
_savegameLoadRequest = true;
@ -109,7 +108,7 @@ void Engine::mainLoop() {
if (_mode == ENGINE_MODE_SMUSH) {
if (g_smush->isPlaying()) {
movieTime_ = g_smush->getMovieTime();
_movieTime = g_smush->getMovieTime();
if (g_smush->isUpdateNeeded()) {
g_driver->prepareSmushFrame(g_smush->getWidth(), g_smush->getHeight(), g_smush->getDstPtr());
g_smush->clearUpdateNeeded();
@ -124,13 +123,13 @@ void Engine::mainLoop() {
if (SCREENBLOCKS_GLOBAL)
screenBlocksReset();
if (currScene_ != NULL) {
if (_currScene != NULL) {
// Update actor costumes
for (actor_list_type::iterator i = actors_.begin(); i != actors_.end(); i++) {
for (actor_list_type::iterator i = _actors.begin(); i != _actors.end(); i++) {
Actor *a = *i;
if (currScene_ != NULL && a->inSet(currScene_->name()) && a->visible())
if (_currScene != NULL && a->inSet(_currScene->name()) && a->visible())
a->update();
}
}
}
g_driver->clearScreen();
@ -138,12 +137,12 @@ void Engine::mainLoop() {
if (SCREENBLOCKS_GLOBAL)
screenBlocksBlitDirtyBlocks();
if (currScene_ != NULL) {
currScene_->drawBackground();
if (_currScene != NULL) {
_currScene->drawBackground();
}
if (g_smush->isPlaying()) {
movieTime_ = g_smush->getMovieTime();
_movieTime = g_smush->getMovieTime();
if (g_smush->isUpdateNeeded()) {
g_driver->prepareSmushFrame(g_smush->getWidth(), g_smush->getHeight(), g_smush->getDstPtr());
g_smush->clearUpdateNeeded();
@ -152,10 +151,10 @@ void Engine::mainLoop() {
g_driver->drawSmushFrame(g_smush->getX(), g_smush->getY());
}
if (currScene_ != NULL) {
currScene_->drawBitmaps(ObjectState::OBJSTATE_UNDERLAY);
currScene_->drawBitmaps(ObjectState::OBJSTATE_STATE);
currScene_->drawBitmaps(ObjectState::OBJSTATE_OVERLAY);
if (_currScene != NULL) {
_currScene->drawBitmaps(ObjectState::OBJSTATE_UNDERLAY);
_currScene->drawBitmaps(ObjectState::OBJSTATE_STATE);
_currScene->drawBitmaps(ObjectState::OBJSTATE_OVERLAY);
}
if (SHOWFPS_GLOBAL)
@ -163,20 +162,20 @@ void Engine::mainLoop() {
g_driver->set3DMode();
if (currScene_ != NULL) {
currScene_->setupCamera();
if (_currScene != NULL) {
_currScene->setupCamera();
// Draw actors
for (actor_list_type::iterator i = actors_.begin(); i != actors_.end(); i++) {
for (actor_list_type::iterator i = _actors.begin(); i != _actors.end(); i++) {
Actor *a = *i;
if (currScene_ != NULL && a->inSet(currScene_->name()) && a->visible())
if (_currScene != NULL && a->inSet(_currScene->name()) && a->visible())
a->draw();
}
//screenBlocksDrawDebug();
}
// Draw text
for (text_list_type::iterator i = textObjects_.begin(); i != textObjects_.end(); i++) {
for (text_list_type::iterator i = _textObjects.begin(); i != _textObjects.end(); i++) {
(*i)->draw();
}
@ -189,26 +188,26 @@ void Engine::mainLoop() {
// Update timing information
unsigned newStart = SDL_GetTicks();
frameTime_ = newStart - frameStart_;
frameStart_ = newStart;
_frameTime = newStart - _frameStart;
_frameStart = newStart;
frameTimeCollection += frameTime_;
frameTimeCollection += _frameTime;
if (frameTimeCollection > 10000) {
frameTimeCollection = 0;
lua_collectgarbage(0);
}
lua_beginblock();
set_frameTime(frameTime_);
set_frameTime(_frameTime);
lua_endblock();
lua_beginblock();
set_movieTime(movieTime_);
set_movieTime(_movieTime);
lua_endblock();
if (SHOWFPS_GLOBAL) {
frameCounter++;
timeAccum += frameTime_;
timeAccum += _frameTime;
if (timeAccum > 1000) {
sprintf(fps, "%7.2f", (double)(frameCounter * 1000) / (double)timeAccum );
frameCounter = 0;
@ -332,7 +331,7 @@ void Engine::setScene(const char *name) {
Block *b = ResourceLoader::instance()->getFileBlock(name);
if (b == NULL)
warning("Could not find scene file %s\n", name);
delete currScene_;
currScene_ = new Scene(name, b->data(), b->len());
delete _currScene;
_currScene = new Scene(name, b->data(), b->len());
delete b;
}

View File

@ -88,9 +88,9 @@ enum {
class Engine {
public:
static Engine *instance() {
if (instance_ == NULL)
instance_ = new Engine;
return instance_;
if (_instance == NULL)
_instance = new Engine;
return _instance;
}
void setMode(int mode) { _mode = mode; }
@ -98,46 +98,46 @@ public:
int getSpeechMode() { return _speechMode; }
void mainLoop();
unsigned frameStart() const { return frameStart_; }
unsigned frameTime() const { return frameTime_; }
unsigned frameStart() const { return _frameStart; }
unsigned frameTime() const { return _frameTime; }
float perSecond(float rate) const { return rate * frameTime_ / 1000; }
float perSecond(float rate) const { return rate * _frameTime / 1000; }
void enableControl(int num) { controlsEnabled_[num] = true; }
void disableControl(int num) { controlsEnabled_[num] = false; }
void enableControl(int num) { _controlsEnabled[num] = true; }
void disableControl(int num) { _controlsEnabled[num] = false; }
void registerActor(Actor *a) { actors_.push_back(a); }
void registerActor(Actor *a) { _actors.push_back(a); }
void setScene(const char *name);
Scene *currScene() { return currScene_; }
const char *sceneName() const { return currScene_->name(); }
Scene *currScene() { return _currScene; }
const char *sceneName() const { return _currScene->name(); }
typedef std::list<Actor *> actor_list_type;
actor_list_type::const_iterator actorsBegin() const {
return actors_.begin();
return _actors.begin();
}
actor_list_type::const_iterator actorsEnd() const {
return actors_.end();
return _actors.end();
}
void setSelectedActor(Actor *a) { selectedActor_ = a; }
Actor *selectedActor() { return selectedActor_; }
void setSelectedActor(Actor *a) { _selectedActor = a; }
Actor *selectedActor() { return _selectedActor; }
typedef std::list<TextObject *> text_list_type;
text_list_type::const_iterator textsBegin() const {
return textObjects_.begin();
return _textObjects.begin();
}
text_list_type::const_iterator textsEnd() const {
return textObjects_.end();
return _textObjects.end();
}
void registerTextObject(TextObject *a) { textObjects_.push_back(a); }
void registerTextObject(TextObject *a) { _textObjects.push_back(a); }
void killTextObject(TextObject *a) {
textObjects_.remove(a);
_textObjects.remove(a);
}
void killTextObjects() {
while (!textObjects_.empty()) {
delete textObjects_.back();
textObjects_.pop_back();
while (!_textObjects.empty()) {
delete _textObjects.back();
_textObjects.pop_back();
}
}
@ -153,22 +153,22 @@ public:
gzFile _savegameFileHandle;
private:
static Engine *instance_;
static Engine *_instance;
Engine();
~Engine() { }
Scene *currScene_;
Scene *_currScene;
int _mode;
int _speechMode;
unsigned frameStart_, frameTime_, movieTime_;
unsigned _frameStart, _frameTime, _movieTime;
bool controlsEnabled_[SDLK_EXTRA_LAST];
bool _controlsEnabled[SDLK_EXTRA_LAST];
actor_list_type actors_;
Actor *selectedActor_;
text_list_type textObjects_;
actor_list_type _actors;
Actor *_selectedActor;
text_list_type _textObjects;
};
#endif

View File

@ -33,151 +33,153 @@ KeyframeAnim::KeyframeAnim(const char *filename, const char *data, int len) :
}
void KeyframeAnim::loadBinary(const char *data, int len) {
flags_ = READ_LE_UINT32(data + 40);
type_ = READ_LE_UINT32(data + 48);
fps_ = get_float(data + 52);
numFrames_ = READ_LE_UINT32(data + 56);
numJoints_ = READ_LE_UINT32(data + 60);
numMarkers_ = READ_LE_UINT32(data + 68);
markers_ = new Marker[numMarkers_];
for (int i = 0; i < numMarkers_; i++) {
markers_[i].frame_ = get_float(data + 72 + 4 * i);
markers_[i].val_ = READ_LE_UINT32(data + 104 + 4 * i);
_flags = READ_LE_UINT32(data + 40);
_type = READ_LE_UINT32(data + 48);
_fps = get_float(data + 52);
_numFrames = READ_LE_UINT32(data + 56);
_numJoints = READ_LE_UINT32(data + 60);
_numMarkers = READ_LE_UINT32(data + 68);
_markers = new Marker[_numMarkers];
for (int i = 0; i < _numMarkers; i++) {
_markers[i]._frame = get_float(data + 72 + 4 * i);
_markers[i]._val = READ_LE_UINT32(data + 104 + 4 * i);
}
nodes_ = new KeyframeNode*[numJoints_];
for (int i = 0; i < numJoints_; i++)
nodes_[i] = NULL;
_nodes = new KeyframeNode *[_numJoints];
for (int i = 0; i < _numJoints; i++)
_nodes[i] = NULL;
const char *dataEnd = data + len;
data += 180;
while (data < dataEnd) {
int nodeNum = READ_LE_UINT32(data + 32);
nodes_[nodeNum] = new KeyframeNode;
nodes_[nodeNum]->loadBinary(data);
_nodes[nodeNum] = new KeyframeNode;
_nodes[nodeNum]->loadBinary(data);
}
}
void KeyframeAnim::loadText(TextSplitter &ts) {
ts.expectString("section: header");
ts.scanString("flags %i", 1, &flags_);
ts.scanString("type %i", 1, &type_);
ts.scanString("frames %d", 1, &numFrames_);
ts.scanString("fps %f", 1, &fps_);
ts.scanString("joints %d", 1, &numJoints_);
ts.scanString("flags %i", 1, &_flags);
ts.scanString("type %i", 1, &_type);
ts.scanString("frames %d", 1, &_numFrames);
ts.scanString("fps %f", 1, &_fps);
ts.scanString("joints %d", 1, &_numJoints);
if (std::strcmp(ts.currentLine(), "section: markers") == 0) {
ts.nextLine();
ts.scanString("markers %d", 1, &numMarkers_);
markers_ = new Marker[numMarkers_];
for (int i = 0; i < numMarkers_; i++)
ts.scanString("%f %d", 2, &markers_[i].frame_, &markers_[i].val_);
ts.scanString("markers %d", 1, &_numMarkers);
_markers = new Marker[_numMarkers];
for (int i = 0; i < _numMarkers; i++)
ts.scanString("%f %d", 2, &_markers[i]._frame, &_markers[i]._val);
} else {
numMarkers_ = 0;
markers_ = NULL;
_numMarkers = 0;
_markers = NULL;
}
ts.expectString("section: keyframe nodes");
int numNodes;
ts.scanString("nodes %d", 1, &numNodes);
nodes_ = new KeyframeNode*[numJoints_];
for (int i = 0; i < numJoints_; i++)
nodes_[i] = NULL;
_nodes = new KeyframeNode *[_numJoints];
for (int i = 0; i < _numJoints; i++)
_nodes[i] = NULL;
for (int i = 0; i < numNodes; i++) {
int which;
ts.scanString("node %d", 1, &which);
nodes_[which] = new KeyframeNode;
nodes_[which]->loadText(ts);
_nodes[which] = new KeyframeNode;
_nodes[which]->loadText(ts);
}
}
KeyframeAnim::~KeyframeAnim() {
for (int i = 0; i < numJoints_; i++)
delete nodes_[i];
delete[] markers_;
for (int i = 0; i < _numJoints; i++)
delete _nodes[i];
delete[] _markers;
}
void KeyframeAnim::animate(Model::HierNode *nodes, float time, int priority1, int priority2) const {
float frame = time * fps_;
if (frame > numFrames_)
frame = numFrames_;
for (int i = 0; i < numJoints_; i++)
if (nodes_[i] != NULL)
nodes_[i]->animate(nodes[i], frame, ((type_ & nodes[i].type_) != 0 ? priority2 : priority1));
float frame = time * _fps;
if (frame > _numFrames)
frame = _numFrames;
for (int i = 0; i < _numJoints; i++)
if (_nodes[i] != NULL)
_nodes[i]->animate(nodes[i], frame, ((_type & nodes[i]._type) != 0 ? priority2 : priority1));
}
void KeyframeAnim::KeyframeEntry::loadBinary(const char *&data) {
frame_ = get_float(data);
flags_ = READ_LE_UINT32(data + 4);
pos_ = get_vector3d(data + 8);
pitch_ = get_float(data + 20);
yaw_ = get_float(data + 24);
roll_ = get_float(data + 28);
dpos_ = get_vector3d(data + 32);
dpitch_ = get_float(data + 44);
dyaw_ = get_float(data + 48);
droll_ = get_float(data + 52);
_frame = get_float(data);
_flags = READ_LE_UINT32(data + 4);
_pos = get_vector3d(data + 8);
_pitch = get_float(data + 20);
_yaw = get_float(data + 24);
_roll = get_float(data + 28);
_dpos = get_vector3d(data + 32);
_dpitch = get_float(data + 44);
_dyaw = get_float(data + 48);
_droll = get_float(data + 52);
data += 56;
}
void KeyframeAnim::KeyframeNode::loadBinary(const char *&data) {
std::memcpy(meshName_, data, 32);
numEntries_ = READ_LE_UINT32(data + 36);
std::memcpy(_meshName, data, 32);
_numEntries = READ_LE_UINT32(data + 36);
data += 44;
entries_ = new KeyframeEntry[numEntries_];
for (int i = 0; i < numEntries_; i++)
entries_[i].loadBinary(data);
_entries = new KeyframeEntry[_numEntries];
for (int i = 0; i < _numEntries; i++)
_entries[i].loadBinary(data);
}
void KeyframeAnim::KeyframeNode::loadText(TextSplitter &ts) {
ts.scanString("mesh name %s", 1, meshName_);
ts.scanString("entries %d", 1, &numEntries_);
entries_ = new KeyframeEntry[numEntries_];
for (int i = 0; i < numEntries_; i++) {
ts.scanString("mesh name %s", 1, _meshName);
ts.scanString("entries %d", 1, &_numEntries);
_entries = new KeyframeEntry[_numEntries];
for (int i = 0; i < _numEntries; i++) {
int which, flags;
float frame, x, y, z, p, yaw, r, dx, dy, dz, dp, dyaw, dr;
ts.scanString(" %d: %f %i %f %f %f %f %f %f", 9, &which, &frame, &flags,
&x, &y, &z, &p, &yaw, &r);
ts.scanString(" %d: %f %i %f %f %f %f %f %f", 9, &which, &frame, &flags, &x, &y, &z, &p, &yaw, &r);
ts.scanString(" %f %f %f %f %f %f", 6, &dx, &dy, &dz, &dp, &dyaw, &dr);
entries_[which].frame_ = frame;
entries_[which].flags_ = flags;
entries_[which].pos_ = Vector3d(x, y, z);
entries_[which].dpos_ = Vector3d(dx, dy, dz);
entries_[which].pitch_ = p;
entries_[which].yaw_ = yaw;
entries_[which].roll_ = r;
entries_[which].dpitch_ = dp;
entries_[which].dyaw_ = dyaw;
entries_[which].droll_ = dr;
_entries[which]._frame = frame;
_entries[which]._flags = flags;
_entries[which]._pos = Vector3d(x, y, z);
_entries[which]._dpos = Vector3d(dx, dy, dz);
_entries[which]._pitch = p;
_entries[which]._yaw = yaw;
_entries[which]._roll = r;
_entries[which]._dpitch = dp;
_entries[which]._dyaw = dyaw;
_entries[which]._droll = dr;
}
}
KeyframeAnim::KeyframeNode::~KeyframeNode() {
delete[] entries_;
delete[] _entries;
}
void KeyframeAnim::KeyframeNode::animate(Model::HierNode &node,
float frame, int priority) const {
if (numEntries_ == 0)
if (_numEntries == 0)
return;
if (priority < node.priority_)
if (priority < node._priority)
return;
// Do a binary search for the nearest previous frame
// Loop invariant: entries_[low].frame_ <= frame < entries_[high].frame_
int low = 0, high = numEntries_;
int low = 0, high = _numEntries;
while (high > low + 1) {
int mid = (low + high) / 2;
if (entries_[mid].frame_ <= frame)
if (_entries[mid]._frame <= frame)
low = mid;
else
high = mid;
}
float dt = frame - entries_[low].frame_;
Vector3d pos = entries_[low].pos_ + dt * entries_[low].dpos_;
float pitch = entries_[low].pitch_ + dt * entries_[low].dpitch_;
float yaw = entries_[low].yaw_ + dt * entries_[low].dyaw_;
float roll = entries_[low].roll_ + dt * entries_[low].droll_;
float dt = frame - _entries[low]._frame;
Vector3d pos = _entries[low]._pos + dt * _entries[low]._dpos;
float pitch = _entries[low]._pitch + dt * _entries[low]._dpitch;
float yaw = _entries[low]._yaw + dt * _entries[low]._dyaw;
float roll = _entries[low]._roll + dt * _entries[low]._droll;
if (pitch > 180)
pitch -= 360;
if (yaw > 180)
@ -185,19 +187,19 @@ void KeyframeAnim::KeyframeNode::animate(Model::HierNode &node,
if (roll > 180)
roll -= 360;
if (priority > node.priority_) {
node.priority_ = priority;
node.totalWeight_ = 1;
node.animPos_ = pos;
node.animPitch_ = pitch;
node.animYaw_ = yaw;
node.animRoll_ = roll;
} else { // priority == node.priority_
node.totalWeight_++;
node.animPos_ += pos;
node.animPitch_ += pitch;
node.animYaw_ += yaw;
node.animRoll_ += roll;
if (priority > node._priority) {
node._priority = priority;
node._totalWeight = 1;
node._animPos = pos;
node._animPitch = pitch;
node._animYaw = yaw;
node._animRoll = roll;
} else { // priority == node._priority
node._totalWeight++;
node._animPos += pos;
node._animPitch += pitch;
node._animYaw += yaw;
node._animRoll += roll;
}
// node

View File

@ -31,29 +31,28 @@ public:
void loadBinary(const char *data, int len);
void loadText(TextSplitter &ts);
void animate(Model::HierNode *nodes, float time,
int priority1 = 1, int priority2 = 5) const;
void animate(Model::HierNode *nodes, float time, int priority1 = 1, int priority2 = 5) const;
float length() const { return numFrames_ / fps_; }
float length() const { return _numFrames / _fps; }
private:
int flags_, type_, numFrames_, numJoints_;
float fps_;
int numMarkers_;
int _flags, _type, _numFrames, _numJoints;
float _fps;
int _numMarkers;
struct Marker {
float frame_;
int val_;
float _frame;
int _val;
};
Marker *markers_;
Marker *_markers;
struct KeyframeEntry {
void loadBinary(const char *&data);
float frame_;
int flags_;
Vector3d pos_, dpos_;
float pitch_, yaw_, roll_, dpitch_, dyaw_, droll_;
float _frame;
int _flags;
Vector3d _pos, _dpos;
float _pitch, _yaw, _roll, _dpitch, _dyaw, _droll;
};
struct KeyframeNode {
@ -62,12 +61,12 @@ private:
~KeyframeNode();
void animate(Model::HierNode &node, float frame, int priority) const;
char meshName_[32];
int numEntries_;
KeyframeEntry *entries_;
char _meshName[32];
int _numEntries;
KeyframeEntry *_entries;
};
KeyframeNode **nodes_;
KeyframeNode **_nodes;
};
#endif

42
lab.cpp
View File

@ -24,12 +24,12 @@
bool Lab::open(const char *filename) {
close();
f_ = std::fopen(filename, "rb");
_f = std::fopen(filename, "rb");
if (!isOpen())
return false;
char header[16];
if (std::fread(header, 1, sizeof(header), f_) < sizeof(header)) {
if (std::fread(header, 1, sizeof(header), _f) < sizeof(header)) {
close();
return false;
}
@ -42,13 +42,13 @@ bool Lab::open(const char *filename) {
int string_table_size = READ_LE_UINT32(header + 12);
char *string_table = new char[string_table_size];
std::fseek(f_, 16 * (num_entries + 1), SEEK_SET);
std::fread(string_table, 1, string_table_size, f_);
std::fseek(_f, 16 * (num_entries + 1), SEEK_SET);
std::fread(string_table, 1, string_table_size, _f);
std::fseek(f_, 16, SEEK_SET);
std::fseek(_f, 16, SEEK_SET);
char binary_entry[16];
for (int i = 0; i < num_entries; i++) {
std::fread(binary_entry, 1, 16, f_);
std::fread(binary_entry, 1, 16, _f);
int fname_offset = READ_LE_UINT32(binary_entry);
int start = READ_LE_UINT32(binary_entry + 4);
int size = READ_LE_UINT32(binary_entry + 8);
@ -56,8 +56,8 @@ bool Lab::open(const char *filename) {
std::string fname = string_table + fname_offset;
std::transform(fname.begin(), fname.end(), fname.begin(), tolower);
file_map_.insert(std::make_pair(fname, LabEntry(start, size)));
file_map_.size();
_file_map.insert(std::make_pair(fname, LabEntry(start, size)));
_file_map.size();
}
delete [] string_table;
@ -65,21 +65,21 @@ bool Lab::open(const char *filename) {
}
bool Lab::fileExists(const char *filename) const {
return find_filename(filename) != file_map_.end();
return find_filename(filename) != _file_map.end();
}
Block *Lab::getFileBlock(const char *filename) const {
file_map_type::const_iterator i = find_filename(filename);
if (i == file_map_.end())
if (i == _file_map.end())
return NULL;
std::fseek(f_, i->second.offset, SEEK_SET);
std::fseek(_f, i->second.offset, SEEK_SET);
// The sound decoder reads up to two bytes past the end of data
// (but shouldn't actually use those bytes). So allocate two extra bytes
// to be safe against crashes.
char *data = new char[i->second.len + 2];
std::fread(data, 1, i->second.len, f_);
std::fread(data, 1, i->second.len, _f);
data[i->second.len] = '\0'; // For valgrind cleanness
data[i->second.len + 1] = '\0';
return new Block(data, i->second.len);
@ -87,17 +87,17 @@ Block *Lab::getFileBlock(const char *filename) const {
std::FILE *Lab::openNewStream(const char *filename) const {
file_map_type::const_iterator i = find_filename(filename);
if (i == file_map_.end())
if (i == _file_map.end())
return NULL;
std::fseek(f_, i->second.offset, SEEK_SET);
std::fseek(_f, i->second.offset, SEEK_SET);
return f_;
return _f;
}
int Lab::fileLength(const char *filename) const {
file_map_type::const_iterator i = find_filename(filename);
if (i == file_map_.end())
if (i == _file_map.end())
return -1;
return i->second.len;
@ -106,12 +106,12 @@ int Lab::fileLength(const char *filename) const {
Lab::file_map_type::const_iterator Lab::find_filename(const char *filename) const {
std::string s = filename;
std::transform(s.begin(), s.end(), s.begin(), tolower);
return file_map_.find(s);
return _file_map.find(s);
}
void Lab::close() {
if (f_ != NULL)
std::fclose(f_);
f_ = NULL;
file_map_.clear();
if (_f != NULL)
std::fclose(_f);
_f = NULL;
_file_map.clear();
}

24
lab.h
View File

@ -24,25 +24,25 @@
class Block {
public:
Block(const char *data, int len) : data_(data), len_(len) {}
const char *data() const { return data_; }
int len() const { return len_; }
Block(const char *data, int len) : _data(data), _len(len) {}
const char *data() const { return _data; }
int len() const { return _len; }
~Block() { delete[] data_; }
~Block() { delete[] _data; }
private:
Block();
const char *data_;
int len_;
bool owner_;
const char *_data;
int _len;
bool _owner;
};
class Lab {
public:
Lab() : f_(NULL) { }
explicit Lab(const char *filename) : f_(NULL) { open(filename); }
Lab() : _f(NULL) { }
explicit Lab(const char *filename) : _f(NULL) { open(filename); }
bool open(const char *filename);
bool isOpen() const { return f_ != NULL; }
bool isOpen() const { return _f != NULL; }
void close();
bool fileExists(const char *filename) const;
Block *getFileBlock(const char *filename) const;
@ -58,9 +58,9 @@ private:
int offset, len;
};
std::FILE *f_;
std::FILE *_f;
typedef std::map<std::string, LabEntry> file_map_type;
file_map_type file_map_;
file_map_type _file_map;
file_map_type::const_iterator find_filename(const char *filename) const;
};

View File

@ -33,57 +33,56 @@ LipSynch::LipSynch(const char *filename, const char *data, int len) :
if (std::memcmp(data, "LIP!", 4) != 0) {
error("Invalid file format in %s\n", filename);
} else {
numEntries_ = (len - 8) / 4;
_numEntries = (len - 8) / 4;
// There are cases where the lipsync file has no entries
if (numEntries_ == 0) {
status_ = false;
entries_ = NULL;
if (_numEntries == 0) {
_status = false;
_entries = NULL;
}
else {
status_ = true;
_status = true;
data += 8;
#ifdef DEBUG_VERBOSE
printf("Reading LipSynch %s, %d entries\n", filename, numEntries_);
#endif
entries_ = new LipEntry[numEntries_];
for (int i = 0; i < numEntries_; i++) {
entries_[i].frame = READ_LE_UINT16(data);
#ifdef DEBUG_VERBOSE
printf("Reading LipSynch %s, %d entries\n", filename, _numEntries);
#endif
_entries = new LipEntry[_numEntries];
for (int i = 0; i < _numEntries; i++) {
_entries[i].frame = READ_LE_UINT16(data);
readPhoneme = READ_LE_UINT16(data + 2);
// Look for the animation corresponding to the phoneme
for (j = 0; j < animTableSize_ &&
readPhoneme != animTable_[j].phoneme; j++);
if ( readPhoneme != animTable_[j].phoneme) {
for (j = 0; j < _animTableSize && readPhoneme != _animTable[j].phoneme; j++);
if (readPhoneme != _animTable[j].phoneme) {
warning("Unknown phoneme: 0x%X in file %s\n", readPhoneme, filename);
entries_[i].anim = 1;
_entries[i].anim = 1;
} else
entries_[i].anim = animTable_[j].anim;
_entries[i].anim = _animTable[j].anim;
data += 4;
}
#ifdef DEBUG_VERBOSE
for (int j = 0; j < numEntries_; j++)
printf("LIP %d) frame %d, anim %d\n", j, entries_[j].frame, entries_[j].anim);
#endif
currEntry_ = 0;
#ifdef DEBUG_VERBOSE
for (int j = 0; j < _numEntries; j++)
printf("LIP %d) frame %d, anim %d\n", j, _entries[j].frame, _entries[j].anim);
#endif
_currEntry = 0;
}
}
}
LipSynch::~LipSynch() {
delete[] entries_;
delete[] _entries;
}
LipSynch::LipEntry LipSynch::getCurrEntry() {
return entries_[currEntry_];
return _entries[_currEntry];
}
void LipSynch::advanceEntry() {
if (currEntry_ < numEntries_)
currEntry_++;
if (_currEntry < _numEntries)
_currEntry++;
}
const LipSynch::PhonemeAnim LipSynch::animTable_[] = {
const LipSynch::PhonemeAnim LipSynch::_animTable[] = {
{0x005F, 0}, {0x0251, 1}, {0x0061, 1}, {0x00E6, 1}, {0x028C, 8},
{0x0254, 1}, {0x0259, 1}, {0x0062, 6}, {0x02A7, 2}, {0x0064, 2},
{0x00F0, 5}, {0x025B, 8}, {0x0268, 8}, {0x025A, 9}, {0x025D, 9},
@ -96,5 +95,4 @@ const LipSynch::PhonemeAnim LipSynch::animTable_[] = {
{0x0292, 2}, {0x002E, 2}
};
const int LipSynch::animTableSize_ = sizeof(LipSynch::animTable_) / sizeof(LipSynch::animTable_[0]);
const int LipSynch::_animTableSize = sizeof(LipSynch::_animTable) / sizeof(LipSynch::_animTable[0]);

View File

@ -34,20 +34,20 @@ public:
LipEntry getCurrEntry();
void advanceEntry();
bool getStatus() const { return status_; }
bool getStatus() const { return _status; }
private:
LipEntry *entries_;
int numEntries_;
int currEntry_;
bool status_;
LipEntry *_entries;
int _numEntries;
int _currEntry;
bool _status;
struct PhonemeAnim {
uint16 phoneme;
uint16 anim;
};
static const PhonemeAnim animTable_[];
static const int animTableSize_;
static const PhonemeAnim _animTable[];
static const int _animTableSize;
};
#endif

View File

@ -22,12 +22,12 @@
#include <cstdio>
#include <cstring>
Localizer *Localizer::instance_ = NULL;
Localizer *Localizer::_instance = NULL;
Localizer *Localizer::instance() {
if (instance_ == NULL)
instance_ = new Localizer;
return instance_;
if (_instance == NULL)
_instance = new Localizer;
return _instance;
}
Localizer::Localizer() {
@ -66,17 +66,20 @@ Localizer::Localizer() {
char *nextline;
for (char *line = data + 4; line != NULL && *line != '\0'; line = nextline) {
nextline = std::strchr(line, '\n');
if (nextline != NULL) {
if (nextline[-1] == '\r')
nextline[-1] = '\0';
nextline++;
}
char *tab = std::strchr(line, '\t');
if (tab == NULL)
continue;
std::string key(line, tab - line);
std::string val = tab + 1;
entries_[key] = val;
_entries[key] = val;
}
delete[] data;
@ -85,13 +88,14 @@ Localizer::Localizer() {
std::string Localizer::localize(const char *str) const {
if (str[0] != '/')
return str;
const char *slash2 = std::strchr(str + 1, '/');
if (slash2 == NULL)
return str;
std::string key(str + 1, slash2 - str - 1);
string_map::const_iterator i = entries_.find(key);
if (i == entries_.end())
string_map::const_iterator i = _entries.find(key);
if (i == _entries.end())
return str;
return "/" + key + '/' + i->second;

View File

@ -31,10 +31,10 @@ private:
Localizer();
~Localizer() { }
static Localizer *instance_;
static Localizer *_instance;
typedef std::map<std::string, std::string> string_map;
string_map entries_;
string_map _entries;
};
#endif

122
lua.cpp
View File

@ -36,28 +36,26 @@
static int actor_tag, color_tag, sound_tag, text_tag, vbuffer_tag, object_tag;
// Yaz: we'll need those later on, you'll see why....
static inline bool isObject(int num) {
if(lua_tag(lua_getparam(num)) != object_tag)
if (lua_tag(lua_getparam(num)) != object_tag)
return false;
return true;
}
static inline bool isActor(int num) {
if(lua_tag(lua_getparam(num)) != actor_tag)
if (lua_tag(lua_getparam(num)) != actor_tag)
return false;
return true;
}
static inline bool isColor(int num) {
if(lua_tag(lua_getparam(num)) != color_tag)
if (lua_tag(lua_getparam(num)) != color_tag)
return false;
return true;
}
static inline bool isSound(int num) {
if(lua_tag(lua_getparam(num)) != sound_tag)
if (lua_tag(lua_getparam(num)) != sound_tag)
return false;
return true;
}
@ -508,6 +506,7 @@ static void PlayActorChore() {
if (!cost)
return;
cost->playChore(num);
}
@ -518,6 +517,7 @@ static void PlayActorChoreLooping() {
if (!cost)
return;
cost->playChoreLooping(num);
}
@ -529,6 +529,7 @@ static void SetActorChoreLooping() {
if (!cost)
return;
cost->setChoreLooping(num, val);
}
@ -555,10 +556,12 @@ static void IsActorChoring() {
lua_pushnil();
return;
}
if (lua_isnil(lua_getparam(2)))
result = cost->isChoring(excludeLooping);
else
result = cost->isChoring(check_int(2), excludeLooping);
if (result < 0)
lua_pushnil();
else
@ -572,25 +575,22 @@ static void ActorLookAt() {
lua_Object z = lua_getparam(4);
lua_Object rate = lua_getparam(5);
if(lua_isnumber(rate))
act->setLookAtRate( luaL_check_number(5) );
if (lua_isnumber(rate))
act->setLookAtRate(luaL_check_number(5));
// Look at nothing
if( lua_isnil(x) ) {
if(act->isLookAtVectorZero()) // already looking at nothing
if (lua_isnil(x)) {
if (act->isLookAtVectorZero()) // already looking at nothing
return;
act->setLookAtVectorZero();
if(lua_isnumber(y))
act->setLookAtRate( luaL_check_number(3) );
if (lua_isnumber(y))
act->setLookAtRate(luaL_check_number(3));
act->setLooking( true );
act->setLooking(true);
return;
}
// look at xyz
else if( lua_isnumber(x) ) {
} else if ( lua_isnumber(x)) { // look at xyz
Vector3d vector;
float fX;
float fY;
@ -598,12 +598,12 @@ static void ActorLookAt() {
fX = luaL_check_number(2);
if( lua_isnumber(y) )
if (lua_isnumber(y))
fY = luaL_check_number(3);
else
fY = 0.f;
if( lua_isnumber(z) )
if (lua_isnumber(z))
fZ = luaL_check_number(4);
else
fZ = 0.f;
@ -611,31 +611,29 @@ static void ActorLookAt() {
vector.set(fX,fY,fZ);
act->setLookAtVector( vector );
}
// look at another actor
else if(isActor(2)) {
} else if (isActor(2)) { // look at another actor
Actor *lookedAct = check_actor(2);
act->setLookAtVector(lookedAct->pos());
if(lua_isnumber(y))
if (lua_isnumber(y))
act->setLookAtRate(luaL_check_number(3));
}
act->setLooking( true );
act->setLooking(true);
}
static void SetActorLookRate() {
Actor *act = check_actor(1);
float rate = luaL_check_number(2);
act->setLookAtRate( rate );
act->setLookAtRate(rate);
}
static void GetActorLookRate() {
Actor *act = check_actor(1);
lua_pushnumber( act->lookAtRate() );
lua_pushnumber(act->lookAtRate());
}
static void SetActorHead() {
@ -647,7 +645,7 @@ static void SetActorHead() {
float maxPitch = luaL_check_number(6);
float maxYaw = luaL_check_number(7);
act->setHead( joint1, joint2, joint3, maxRoll, maxPitch, maxYaw );
act->setHead(joint1, joint2, joint3, maxRoll, maxPitch, maxYaw);
}
static void SetActorFollowBoxes() { // Constrain actor to walkplanes?
@ -657,13 +655,11 @@ static void SetActorFollowBoxes() { // Constrain actor to walkplanes?
act->setConstrain(constrain);
}
/////////////
static void GetVisibleThings() {
lua_Object result = lua_createtable();
Actor *sel = Engine::instance()->selectedActor();
for (Engine::actor_list_type::const_iterator i = Engine::instance()->actorsBegin();
i != Engine::instance()->actorsEnd(); i++) {
if (! (*i)->inSet(Engine::instance()->sceneName()))
for (Engine::actor_list_type::const_iterator i = Engine::instance()->actorsBegin(); i != Engine::instance()->actorsEnd(); i++) {
if (!(*i)->inSet(Engine::instance()->sceneName()))
continue;
if (sel->angleTo(*(*i)) < 90) {
lua_pushobject(result);
@ -710,7 +706,7 @@ static void ShutUpActor() {
static void HardwareAccelerated() {
// FIXME: Are we always in HW accelerated ?
lua_pushnumber( true );
lua_pushnumber(true);
}
// Sector functions
@ -723,8 +719,7 @@ static void GetActorSector(void) {
lua_pushnumber(result->id());
lua_pushstring(const_cast<char *>(result->name()));
lua_pushnumber(result->type());
}
else {
} else {
lua_pushnil();
lua_pushnil();
lua_pushnil();
@ -742,7 +737,7 @@ static void IsActorInSector(void) {
if (sector->visible() && strstr(sector->name(), name)) {
if (sector->isPointInSector(act->pos())) {
lua_pushnumber(sector->id());
lua_pushstring((char*)sector->name());
lua_pushstring((char *)sector->name());
lua_pushnumber(sector->type());
}
}
@ -844,12 +839,12 @@ static void GetShrinkPos() {
// Sound functions
enum ImuseParam {
IM_SOUND_PLAY_COUNT = 256,
IM_SOUND_PEND_COUNT = 512,
IM_SOUND_GROUP = 1024,
IM_SOUND_PRIORITY = 1280,
IM_SOUND_VOL = 1536,
IM_SOUND_PAN = 1792
IM_SOUND_PLAY_COUNT = 0x100,
IM_SOUND_PEND_COUNT = 0x200,
IM_SOUND_GROUP = 0x400,
IM_SOUND_PRIORITY = 0x500,
IM_SOUND_VOL = 0x600,
IM_SOUND_PAN = 0x700
};
void ImStartSound() {
@ -916,7 +911,6 @@ void ImSetSequence() {
Mixer::instance()->setImuseSeq(seq);
}
// Timing functions
void set_frameTime(float frameTime) {
lua_pushobject(lua_getglobal("system"));
lua_pushstring("frameTime");
@ -936,7 +930,6 @@ void PerSecond() {
lua_pushnumber(Engine::instance()->perSecond(rate));
}
// Game control functions
void EnableControl() {
int num = check_control(1);
Engine::instance()->enableControl(num);
@ -959,7 +952,6 @@ void GetControlState() {
}
}
// Text functions
static void MakeTextObject() {
char *line = lua_getstring(lua_getparam(1)), *key_text = NULL;
lua_Object table_obj = lua_getparam(2), key;
@ -967,7 +959,7 @@ static void MakeTextObject() {
Color *fgColor = NULL;
TextObject *textObject;
while(1) {
while (1) {
lua_pushobject(table_obj);
if (key_text)
lua_pushobject(key);
@ -1044,14 +1036,15 @@ static void ChangeTextObject_Real(char *keyName, void *data) {
// FIXME: X/Y sets depend on GetTextObjectDimensions
if (strstr(keyName, "fgcolor"))
if (strstr(keyName, "fgcolor")) {
modifyObject->setColor(check_color(2));
else if (strstr(keyName, "x"))
;//modifyObject->setX( atoi(lua_getstring(keyValue)) );
else if (strstr(keyName, "y"))
;//modifyObject->setY( atoi(lua_getstring(keyValue)) );
else
} else if (strstr(keyName, "x")) {
//modifyObject->setX(atoi(lua_getstring(keyValue)));
} else if (strstr(keyName, "y")) {
//modifyObject->setY(atoi(lua_getstring(keyValue)));
} else {
printf("ChangeTextObject() - Unknown key %s\n", keyName);
}
}
// Callback from table walk method in Main CTO function
@ -1070,8 +1063,7 @@ static void ChangeTextObject() {
lua_Object tableObj = lua_getparam(2);
TextObject *modifyObject = NULL;
for (Engine::text_list_type::const_iterator i = Engine::instance()->textsBegin();
i != Engine::instance()->textsEnd(); i++) {
for (Engine::text_list_type::const_iterator i = Engine::instance()->textsBegin(); i != Engine::instance()->textsEnd(); i++) {
TextObject *textO = *i;
if (strstr(textO->name(), textID)) {
@ -1146,7 +1138,6 @@ static void PauseMovie() {
g_smush->pause(lua_isnil(lua_getparam(1)) != 0);
}
static void GetTextCharPosition() {
warning("STUB GetTextCharPosition(\"%s\", %d)",
lua_getstring(lua_getparam(1)), lua_getnumber(lua_getparam(2)));
@ -1166,6 +1157,7 @@ static void NewObjectState() {
OBJSTATE_OVERLAY = 2,
OBJSTATE_STATE = 3
};
ObjectState *object = NULL;
int setupID = check_int(1); // Setup ID
@ -1236,8 +1228,7 @@ static void stubWarning(char *funcName) {
}
else if (lua_tag(lua_getparam(i)) == color_tag) {
Color *c = check_color(i);
fprintf(stderr, "<color #%02x%02x%02x>",
c->red(), c->green(), c->blue());
fprintf(stderr, "<color #%02x%02x%02x>", c->red(), c->green(), c->blue());
}
else if (lua_tag(lua_getparam(i)) == sound_tag) {
Sound *s = check_sound(i);
@ -1245,8 +1236,7 @@ static void stubWarning(char *funcName) {
}
else
fprintf(stderr, "<userdata %p>", lua_getuserdata(lua_getparam(i)));
}
else if (lua_isfunction(lua_getparam(i)))
} else if (lua_isfunction(lua_getparam(i)))
fprintf(stderr, "<function>");
else if (lua_isnumber(lua_getparam(i)))
fprintf(stderr, "%g", lua_getnumber(lua_getparam(i)));
@ -1269,7 +1259,7 @@ static void BlastText() {
int x = 0, y = 0, height = 0, width = 0;
Color *fgColor = NULL;
while(1) {
while (1) {
lua_pushobject(table_obj);
if (key_text)
lua_pushobject(key);
@ -1277,11 +1267,12 @@ static void BlastText() {
lua_pushnil();
lua_call("next");
key=lua_getresult(1);
key = lua_getresult(1);
if (lua_isnil(key))
break;
key_text=lua_getstring(key);
key_text = lua_getstring(key);
//val_text=lua_getstring(lua_getresult(2));
if (strstr(key_text, "x"))
x = atoi(lua_getstring(lua_getresult(2)));
@ -2118,11 +2109,11 @@ int bundle_dofile(const char *filename) {
// d:\grimFandango\Scripts\foo.lua
if (std::strstr(filename, "Scripts\\") == NULL)
warning("Cannot find script %s\n", filename);
return 2;
}
int result = lua_dobuffer(const_cast<char *>(b->data()), b->len(),
const_cast<char *>(filename));
int result = lua_dobuffer(const_cast<char *>(b->data()), b->len(), const_cast<char *>(filename));
delete b;
return result;
}
@ -2138,16 +2129,17 @@ lua_Object getEventHandler(const char *name) {
if (lua_istable(handler)) {
lua_pushobject(handler); // Push handler object
lua_pushobject(handler); // For gettable
lua_pushstring(const_cast<char *>(name));
handler = lua_gettable();
if (lua_isnil(handler))
return LUA_NOOBJECT;
}
if (! lua_isfunction(handler)) {
if (!lua_isfunction(handler)) {
warning("Invalid event handler %s", name);
return LUA_NOOBJECT;
}
return handler;
}

View File

@ -84,7 +84,7 @@ int main(int argc, char *argv[]) {
ZBUFFER_GLOBAL = parseBoolStr(Registry::instance()->get("zbuffer"));
SCREENBLOCKS_GLOBAL = parseBoolStr(Registry::instance()->get("screenblocks"));
SHOWFPS_GLOBAL = parseBoolStr(Registry::instance()->get("fps"));
for (i=1;i<argc;i++) {
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-zbuffer") == 0)
ZBUFFER_GLOBAL = true;
else if (strcmp(argv[i], "-nozbuffer") == 0)
@ -167,8 +167,8 @@ int main(int argc, char *argv[]) {
return 0;
}
StackLock::StackLock(MutexRef mutex)
: _mutex(mutex) {
StackLock::StackLock(MutexRef mutex) :
_mutex(mutex) {
lock_mutex(_mutex);
}
@ -177,17 +177,17 @@ StackLock::~StackLock() {
}
MutexRef create_mutex() {
return (MutexRef) SDL_CreateMutex();
return (MutexRef)SDL_CreateMutex();
}
void lock_mutex(MutexRef mutex) {
SDL_mutexP((SDL_mutex *) mutex);
SDL_mutexP((SDL_mutex *)mutex);
}
void unlock_mutex(MutexRef mutex) {
SDL_mutexV((SDL_mutex *) mutex);
SDL_mutexV((SDL_mutex *)mutex);
}
void delete_mutex(MutexRef mutex) {
SDL_DestroyMutex((SDL_mutex *) mutex);
SDL_DestroyMutex((SDL_mutex *)mutex);
}

View File

@ -27,16 +27,16 @@ Material::Material(const char *filename, const char *data, int len, const CMap &
if (len < 4 || memcmp(data, "MAT ", 4) != 0)
error("invalid magic loading texture\n");
num_images_ = READ_LE_UINT32(data + 12);
curr_image_ = 0;
width_ = READ_LE_UINT32(data + 76 + num_images_ * 40);
height_ = READ_LE_UINT32(data + 80 + num_images_ * 40);
_num_images = READ_LE_UINT32(data + 12);
_curr_image = 0;
_width = READ_LE_UINT32(data + 76 + _num_images * 40);
_height = READ_LE_UINT32(data + 80 + _num_images * 40);
if ((width_ == 0) || (height_ == 0)) {
warning("bad texture size (%dx%d) for texture %s\n", width_, height_, filename);
if ((_width == 0) || (_height == 0)) {
warning("bad texture size (%dx%d) for texture %s\n", _width, _height, filename);
}
data += 100 + num_images_ * 40;
data += 100 + _num_images * 40;
g_driver->createMaterial(this, data, &cmap);
}

View File

@ -34,17 +34,17 @@ public:
void select() const;
// Set which image in an animated texture to use
void setNumber(int n) { curr_image_ = n; }
void setNumber(int n) { _curr_image = n; }
int numImages() const { return num_images_; }
int currentImage() const { return curr_image_; }
int numImages() const { return _num_images; }
int currentImage() const { return _curr_image; }
~Material();
//private:
int num_images_, curr_image_;
int width_, height_;
GLuint *textures_;
int _num_images, _curr_image;
int _width, _height;
GLuint *_textures;
};
#endif

View File

@ -19,9 +19,9 @@
#include "matrix3.h"
void Matrix3::setAsIdentity() {
right_.set(1.f, 0.f, 0.f);
up_.set(0.f, 1.f, 0.f);
at_.set(0.f, 0.f, 0.f);
_right.set(1.f, 0.f, 0.f);
_up.set(0.f, 1.f, 0.f);
_at.set(0.f, 0.f, 0.f);
}
void Matrix3::buildFromPitchYawRoll(float pitch, float yaw, float roll) {
@ -57,9 +57,9 @@ void Matrix3::constructAroundPitch(float pitch) {
cosa = (float)cos(DegreeToRadian(pitch));
sina = (float)sin(DegreeToRadian(pitch));
right_.set(1.f, 0.f, 0.f);
up_.set(0.f, cosa, -sina);
at_.set(0.f, sina, cosa);
_right.set(1.f, 0.f, 0.f);
_up.set(0.f, cosa, -sina);
_at.set(0.f, sina, cosa);
}
// up
@ -70,9 +70,9 @@ void Matrix3::constructAroundYaw(float yaw) {
cosa = (float)cos(DegreeToRadian(yaw));
sina = (float)sin(DegreeToRadian(yaw));
right_.set(cosa, 0.f, sina);
up_.set(0.f, 1.f, 0.f);
at_.set(-sina, 0.f, cosa);
_right.set(cosa, 0.f, sina);
_up.set(0.f, 1.f, 0.f);
_at.set(-sina, 0.f, cosa);
}
// at
@ -83,9 +83,9 @@ void Matrix3::constructAroundRoll(float roll) {
cosa = (float)cos(DegreeToRadian(roll));
sina = (float)sin(DegreeToRadian(roll));
right_.set(cosa, -sina, 0.f);
up_.set(sina, cosa, 0.f);
at_.set(0.f, 0.f, 1.f);
_right.set(cosa, -sina, 0.f);
_up.set(sina, cosa, 0.f);
_at.set(0.f, 0.f, 1.f);
}
/*
@ -104,25 +104,25 @@ void Matrix3::getPitchYawRoll(float* pPitch, float* pYaw, float* pRoll) {
float angle_y;
float angle_z;
angle_y = D = asin(right_.z()); /* Calculate Y-axis angle */
angle_y = D = asin(_right.z()); /* Calculate Y-axis angle */
C = cos(angle_y);
angle_y = RadianToDegree(angle_y);
if (fabs( C ) > 0.005) { /* Gimball lock? */
ftrx = at_.z() / C; /* No, so get X-axis angle */
ftry = -up_.z() / C;
ftrx = _at.z() / C; /* No, so get X-axis angle */
ftry = -_up.z() / C;
angle_x = RadianToDegree(atan2( ftry, ftrx ));
angle_x = RadianToDegree(atan2(ftry, ftrx));
ftrx = right_.x() / C; /* Get Z-axis angle */
ftry = -right_.y() / C;
ftrx = _right.x() / C; /* Get Z-axis angle */
ftry = -_right.y() / C;
angle_z = RadianToDegree(atan2( ftry, ftrx ));
angle_z = RadianToDegree(atan2(ftry, ftrx));
} else { /* Gimball lock has occurred */
angle_x = 0; /* Set X-axis angle to zqero */
ftrx = up_.y(); /* And calculate Z-axis angle */
ftry = up_.x();
ftrx = _up.y(); /* And calculate Z-axis angle */
ftry = _up.x();
angle_z = RadianToDegree(atan2(ftry, ftrx));
}
@ -132,13 +132,13 @@ void Matrix3::getPitchYawRoll(float* pPitch, float* pYaw, float* pRoll) {
if (angle_y < 0) angle_y += 360;
if (angle_z < 0) angle_z += 360;
if( pPitch)
if (pPitch)
*pPitch = angle_x;
if( pYaw )
if (pYaw)
*pYaw = angle_y;
if( pRoll )
if (pRoll)
*pRoll = angle_z;
}
@ -171,9 +171,9 @@ void Matrix3::transform(Vector3d* v) {
float y;
float z;
x = v->dotProduct(right_.x(), up_.x(), at_.x());
y = v->dotProduct(right_.x(), up_.x(), at_.x());
z = v->dotProduct(right_.x(), up_.x(), at_.x());
x = v->dotProduct(_right.x(), _up.x(), _at.x());
y = v->dotProduct(_right.x(), _up.x(), _at.x());
z = v->dotProduct(_right.x(), _up.x(), _at.x());
v->set(x, y, z);
}

View File

@ -23,53 +23,53 @@
// matrix 3 is a rotation matrix
class Matrix3{
public:
Vector3d right_;
Vector3d up_;
Vector3d at_;
Vector3d _right;
Vector3d _up;
Vector3d _at;
void buildFromPitchYawRoll( float pitch, float yaw, float roll );
void setAsIdentity(void);
void buildFromPitchYawRoll(float pitch, float yaw, float roll);
void setAsIdentity();
void constructAroundPitch( float pitch );
void constructAroundYaw( float pitch );
void constructAroundRoll( float pitch );
void constructAroundPitch(float pitch);
void constructAroundYaw(float pitch);
void constructAroundRoll(float pitch);
void getPitchYawRoll( float* pPitch, float* pYaw, float* pRoll );
void getPitchYawRoll(float* pPitch, float* pYaw, float* pRoll);
float getPitch();
float getYaw();
float getRoll();
void transform( Vector3d* v );
void transform(Vector3d* v);
// operators
Matrix3& operator *=(const Matrix3& s) {
float x, y, z;
x = right_.dotProduct( s.right_.x(), s.up_.x(), s.at_.x() );
y = right_.dotProduct( s.right_.y(), s.up_.y(), s.at_.y() );
z = right_.dotProduct( s.right_.z(), s.up_.z(), s.at_.z() );
x = _right.dotProduct(s._right.x(), s._up.x(), s._at.x());
y = _right.dotProduct(s._right.y(), s._up.y(), s._at.y());
z = _right.dotProduct(s._right.z(), s._up.z(), s._at.z());
right_.set( x, y, z );
_right.set(x, y, z);
x = up_.dotProduct( s.right_.x(), s.up_.x(), s.at_.x() );
y = up_.dotProduct( s.right_.y(), s.up_.y(), s.at_.y() );
z = up_.dotProduct( s.right_.z(), s.up_.z(), s.at_.z() );
x = _up.dotProduct(s._right.x(), s._up.x(), s._at.x());
y = _up.dotProduct(s._right.y(), s._up.y(), s._at.y());
z = _up.dotProduct(s._right.z(), s._up.z(), s._at.z());
up_.set( x, y, z );
_up.set( x, y, z );
x = at_.dotProduct( s.right_.x(), s.up_.x(), s.at_.x() );
y = at_.dotProduct( s.right_.y(), s.up_.y(), s.at_.y() );
z = at_.dotProduct( s.right_.z(), s.up_.z(), s.at_.z() );
x = _at.dotProduct(s._right.x(), s._up.x(), s._at.x());
y = _at.dotProduct(s._right.y(), s._up.y(), s._at.y());
z = _at.dotProduct(s._right.z(), s._up.z(), s._at.z());
at_.set( x, y, z );
_at.set(x, y, z);
return *this;
}
Matrix3& operator =(const Matrix3& s) {
right_ = s.right_;
up_ = s.up_;
at_ = s.at_;
_right = s._right;
_up = s._up;
_at = s._at;
return *this;
}

View File

@ -17,18 +17,16 @@
#include "matrix4.h"
Matrix4::Matrix4( void ) {
pos_.set(0.f, 0.f, 0.f);
rot_.setAsIdentity();
Matrix4::Matrix4() {
_pos.set(0.f, 0.f, 0.f);
_rot.setAsIdentity();
}
void Matrix4::translate(float x, float y, float z) {
Vector3d v;
v.set(x, y, z);
rot_.transform(&v);
pos_ += v;
_rot.transform(&v);
_pos += v;
}

View File

@ -24,14 +24,14 @@
// matrix 4 is a rotation matrix + position
class Matrix4 {
public:
Matrix3 rot_;
Vector3d pos_;
Matrix3 _rot;
Vector3d _pos;
Matrix4();
Matrix4& operator =(const Matrix4& s) {
pos_ = s.pos_;
rot_ = s.rot_;
_pos = s._pos;
_rot = s._rot;
return *this;
}
@ -39,12 +39,10 @@ public:
Matrix4& operator *=(const Matrix4& s) {
Vector3d v;
v = s.pos_;
rot_.transform(&v);
pos_+=v;
rot_ *= s.rot_;
v = s._pos;
_rot.transform(&v);
_pos += v;
_rot *= s._rot;
return *this;
}

424
model.cpp
View File

@ -37,91 +37,91 @@ Model::Model(const char *filename, const char *data, int len, const CMap &cmap)
}
void Model::loadBinary(const char *data, const CMap &cmap) {
numMaterials_ = READ_LE_UINT32(data + 4);
_numMaterials = READ_LE_UINT32(data + 4);
data += 8;
materials_ = new ResPtr<Material>[numMaterials_];
for (int i = 0; i < numMaterials_; i++) {
materials_[i] = ResourceLoader::instance()->loadMaterial(data, cmap);
_materials = new ResPtr<Material>[_numMaterials];
for (int i = 0; i < _numMaterials; i++) {
_materials[i] = ResourceLoader::instance()->loadMaterial(data, cmap);
data += 32;
}
data += 32; // skip name
numGeosets_ = READ_LE_UINT32(data + 4);
_numGeosets = READ_LE_UINT32(data + 4);
data += 8;
geosets_ = new Geoset[numGeosets_];
for (int i = 0; i < numGeosets_; i++)
geosets_[i].loadBinary(data, materials_);
numHierNodes_ = READ_LE_UINT32(data + 4);
_geosets = new Geoset[_numGeosets];
for (int i = 0; i < _numGeosets; i++)
_geosets[i].loadBinary(data, _materials);
_numHierNodes = READ_LE_UINT32(data + 4);
data += 8;
rootHierNode_ = new HierNode[numHierNodes_];
for (int i = 0; i < numHierNodes_; i++)
rootHierNode_[i].loadBinary(data, rootHierNode_, geosets_[0]);
radius_ = get_float(data);
insertOffset_ = get_vector3d(data + 40);
_rootHierNode = new HierNode[_numHierNodes];
for (int i = 0; i < _numHierNodes; i++)
_rootHierNode[i].loadBinary(data, _rootHierNode, _geosets[0]);
_radius = get_float(data);
_insertOffset = get_vector3d(data + 40);
}
Model::~Model() {
delete[] materials_;
delete[] geosets_;
delete[] rootHierNode_;
delete[] _materials;
delete[] _geosets;
delete[] _rootHierNode;
}
void Model::Geoset::loadBinary(const char *&data, ResPtr<Material> *materials) {
numMeshes_ = READ_LE_UINT32(data);
_numMeshes = READ_LE_UINT32(data);
data += 4;
meshes_ = new Mesh[numMeshes_];
for (int i = 0; i < numMeshes_; i++)
meshes_[i].loadBinary(data, materials);
_meshes = new Mesh[_numMeshes];
for (int i = 0; i < _numMeshes; i++)
_meshes[i].loadBinary(data, materials);
}
Model::Geoset::~Geoset() {
delete[] meshes_;
delete[] _meshes;
}
void Model::Mesh::loadBinary(const char *&data, ResPtr<Material> *materials) {
memcpy(name_, data, 32);
geometryMode_ = READ_LE_UINT32(data + 36);
lightingMode_ = READ_LE_UINT32(data + 40);
textureMode_ = READ_LE_UINT32(data + 44);
numVertices_ = READ_LE_UINT32(data + 48);
numTextureVerts_ = READ_LE_UINT32(data + 52);
numFaces_ = READ_LE_UINT32(data + 56);
vertices_ = new float[3 * numVertices_];
verticesI_ = new float[numVertices_];
vertNormals_ = new float[3 * numVertices_];
textureVerts_ = new float[2 * numTextureVerts_];
memcpy(_name, data, 32);
_geometryMode = READ_LE_UINT32(data + 36);
_lightingMode = READ_LE_UINT32(data + 40);
_textureMode = READ_LE_UINT32(data + 44);
_numVertices = READ_LE_UINT32(data + 48);
_numTextureVerts = READ_LE_UINT32(data + 52);
_numFaces = READ_LE_UINT32(data + 56);
_vertices = new float[3 * _numVertices];
_verticesI = new float[_numVertices];
_vertNormals = new float[3 * _numVertices];
_textureVerts = new float[2 * _numTextureVerts];
data += 60;
for (int i = 0; i < 3 * numVertices_; i++) {
vertices_[i] = get_float(data);
for (int i = 0; i < 3 * _numVertices; i++) {
_vertices[i] = get_float(data);
data += 4;
}
for (int i = 0; i < 2 * numTextureVerts_; i++) {
textureVerts_[i] = get_float(data);
for (int i = 0; i < 2 * _numTextureVerts; i++) {
_textureVerts[i] = get_float(data);
data += 4;
}
for (int i = 0; i < numVertices_; i++) {
verticesI_[i] = get_float(data);
for (int i = 0; i < _numVertices; i++) {
_verticesI[i] = get_float(data);
data += 4;
}
data += numVertices_ * 4;
faces_ = new Face[numFaces_];
for (int i = 0; i < numFaces_; i++)
faces_[i].loadBinary(data, materials);
vertNormals_ = new float[3 * numVertices_];
for (int i = 0; i < 3 * numVertices_; i++) {
vertNormals_[i] = get_float(data);
data += _numVertices * 4;
_faces = new Face[_numFaces];
for (int i = 0; i < _numFaces; i++)
_faces[i].loadBinary(data, materials);
_vertNormals = new float[3 * _numVertices];
for (int i = 0; i < 3 * _numVertices; i++) {
_vertNormals[i] = get_float(data);
data += 4;
}
shadow_ = READ_LE_UINT32(data);
radius_ = get_float(data + 8);
_shadow = READ_LE_UINT32(data);
_radius = get_float(data + 8);
data += 36;
}
Model::Mesh::~Mesh() {
delete[] vertices_;
delete[] verticesI_;
delete[] vertNormals_;
delete[] textureVerts_;
delete[] faces_;
delete[] _vertices;
delete[] _verticesI;
delete[] _vertNormals;
delete[] _textureVerts;
delete[] _faces;
}
void Model::Mesh::update() {
@ -129,108 +129,108 @@ void Model::Mesh::update() {
}
void Model::Face::loadBinary(const char *&data, ResPtr<Material> *materials) {
type_ = READ_LE_UINT32(data + 4);
geo_ = READ_LE_UINT32(data + 8);
light_ = READ_LE_UINT32(data + 12);
tex_ = READ_LE_UINT32(data + 16);
numVertices_ = READ_LE_UINT32(data + 20);
_type = READ_LE_UINT32(data + 4);
_geo = READ_LE_UINT32(data + 8);
_light = READ_LE_UINT32(data + 12);
_tex = READ_LE_UINT32(data + 16);
_numVertices = READ_LE_UINT32(data + 20);
int texPtr = READ_LE_UINT32(data + 28);
int materialPtr = READ_LE_UINT32(data + 32);
extraLight_ = get_float(data + 48);
normal_ = get_vector3d(data + 64);
_extraLight = get_float(data + 48);
_normal = get_vector3d(data + 64);
data += 76;
vertices_ = new int[numVertices_];
for (int i = 0; i < numVertices_; i++) {
vertices_[i] = READ_LE_UINT32(data);
_vertices = new int[_numVertices];
for (int i = 0; i < _numVertices; i++) {
_vertices[i] = READ_LE_UINT32(data);
data += 4;
}
if (texPtr == 0)
texVertices_ = NULL;
if (texPtr == NULL)
_texVertices = NULL;
else {
texVertices_ = new int[numVertices_];
for (int i = 0; i < numVertices_; i++) {
texVertices_[i] = READ_LE_UINT32(data);
_texVertices = new int[_numVertices];
for (int i = 0; i < _numVertices; i++) {
_texVertices[i] = READ_LE_UINT32(data);
data += 4;
}
}
if (materialPtr == 0)
material_ = 0;
_material = 0;
else {
material_ = materials[READ_LE_UINT32(data)];
_material = materials[READ_LE_UINT32(data)];
data += 4;
}
}
Model::Face::~Face() {
delete[] vertices_;
delete[] texVertices_;
delete[] _vertices;
delete[] _texVertices;
}
void Model::HierNode::loadBinary(const char *&data, Model::HierNode *hierNodes, const Geoset &g) {
memcpy(name_, data, 64);
flags_ = READ_LE_UINT32(data + 64);
type_ = READ_LE_UINT32(data + 72);
memcpy(_name, data, 64);
_flags = READ_LE_UINT32(data + 64);
_type = READ_LE_UINT32(data + 72);
int meshNum = READ_LE_UINT32(data + 76);
if (meshNum < 0)
mesh_ = NULL;
_mesh = NULL;
else
mesh_ = g.meshes_ + meshNum;
depth_ = READ_LE_UINT32(data + 80);
_mesh = g._meshes + meshNum;
_depth = READ_LE_UINT32(data + 80);
int parentPtr = READ_LE_UINT32(data + 84);
numChildren_ = READ_LE_UINT32(data + 88);
_numChildren = READ_LE_UINT32(data + 88);
int childPtr = READ_LE_UINT32(data + 92);
int siblingPtr = READ_LE_UINT32(data + 96);
pivot_ = get_vector3d(data + 100);
pos_ = get_vector3d(data + 112);
pitch_ = get_float(data + 124);
yaw_ = get_float(data + 128);
roll_ = get_float(data + 132);
animPos_ = pos_;
animPitch_ = pitch_;
animYaw_ = yaw_;
animRoll_ = roll_;
priority_ = -1;
totalWeight_ = 1;
_pivot = get_vector3d(data + 100);
_pos = get_vector3d(data + 112);
_pitch = get_float(data + 124);
_yaw = get_float(data + 128);
_roll = get_float(data + 132);
_animPos = _pos;
_animPitch = _pitch;
_animYaw = _yaw;
_animRoll = _roll;
_priority = -1;
_totalWeight = 1;
data += 184;
if (parentPtr != 0) {
parent_ = hierNodes + READ_LE_UINT32(data);
_parent = hierNodes + READ_LE_UINT32(data);
data += 4;
} else
parent_ = NULL;
_parent = NULL;
if (childPtr != 0) {
child_ = hierNodes + READ_LE_UINT32(data);
_child = hierNodes + READ_LE_UINT32(data);
data += 4;
} else
child_ = NULL;
_child = NULL;
if (siblingPtr != 0) {
sibling_ = hierNodes + READ_LE_UINT32(data);
_sibling = hierNodes + READ_LE_UINT32(data);
data += 4;
} else
sibling_ = NULL;
_sibling = NULL;
meshVisible_ = true;
hierVisible_ = true;
totalWeight_ = 1;
_meshVisible = true;
_hierVisible = true;
_totalWeight = 1;
}
void Model::draw() const {
rootHierNode_->draw();
_rootHierNode->draw();
}
Model::HierNode *Model::copyHierarchy() {
HierNode *result = new HierNode[numHierNodes_];
std::memcpy(result, rootHierNode_, numHierNodes_ * sizeof(HierNode));
HierNode *result = new HierNode[_numHierNodes];
std::memcpy(result, _rootHierNode, _numHierNodes * sizeof(HierNode));
// Now adjust pointers
for (int i = 0; i < numHierNodes_; i++) {
if (result[i].parent_ != NULL)
result[i].parent_ = result + (rootHierNode_[i].parent_ - rootHierNode_);
if (result[i].child_ != NULL)
result[i].child_ = result + (rootHierNode_[i].child_ - rootHierNode_);
if (result[i].sibling_ != NULL)
result[i].sibling_ = result + (rootHierNode_[i].sibling_ - rootHierNode_);
for (int i = 0; i < _numHierNodes; i++) {
if (result[i]._parent != NULL)
result[i]._parent = result + (_rootHierNode[i]._parent - _rootHierNode);
if (result[i]._child != NULL)
result[i]._child = result + (_rootHierNode[i]._child - _rootHierNode);
if (result[i]._sibling != NULL)
result[i]._sibling = result + (_rootHierNode[i]._sibling - _rootHierNode);
}
return result;
}
@ -239,70 +239,68 @@ void Model::loadText(TextSplitter &ts, const CMap &cmap) {
ts.expectString("section: header");
int major, minor;
ts.scanString("3do %d.%d", 2, &major, &minor);
ts.expectString("section: modelresource");
ts.scanString("materials %d", 1, &numMaterials_);
materials_ = new ResPtr<Material>[numMaterials_];
for (int i = 0; i < numMaterials_; i++) {
ts.scanString("materials %d", 1, &_numMaterials);
_materials = new ResPtr<Material>[_numMaterials];
for (int i = 0; i < _numMaterials; i++) {
int num;
char name[32];
ts.scanString("%d: %32s", 2, &num, name);
materials_[num] = ResourceLoader::instance()->loadMaterial(name, cmap);
_materials[num] = ResourceLoader::instance()->loadMaterial(name, cmap);
}
ts.expectString("section: geometrydef");
ts.scanString("radius %f", 1, &radius_);
ts.scanString("insert offset %f %f %f", 3,
&insertOffset_.x(), &insertOffset_.y(), &insertOffset_.z());
ts.scanString("geosets %d", 1, &numGeosets_);
geosets_ = new Geoset[numGeosets_];
for (int i = 0; i < numGeosets_; i++) {
ts.scanString("radius %f", 1, &_radius);
ts.scanString("insert offset %f %f %f", 3, &_insertOffset.x(), &_insertOffset.y(), &_insertOffset.z());
ts.scanString("geosets %d", 1, &_numGeosets);
_geosets = new Geoset[_numGeosets];
for (int i = 0; i < _numGeosets; i++) {
int num;
ts.scanString("geoset %d", 1, &num);
geosets_[num].loadText(ts, materials_);
_geosets[num].loadText(ts, _materials);
}
ts.expectString("section: hierarchydef");
ts.scanString("hierarchy nodes %d", 1, &numHierNodes_);
rootHierNode_ = new HierNode[numHierNodes_];
for (int i = 0; i < numHierNodes_; i++) {
ts.scanString("hierarchy nodes %d", 1, &_numHierNodes);
_rootHierNode = new HierNode[_numHierNodes];
for (int i = 0; i < _numHierNodes; i++) {
int num, flags, type, mesh, parent, child, sibling, numChildren;
float x, y, z, pitch, yaw, roll, pivotx, pivoty, pivotz;
char name[64];
ts.scanString(" %d: %i %i %d %d %d %d %d %f %f %f %f %f %f %f %f %f %64s",
18, &num, &flags, &type, &mesh, &parent, &child, &sibling,
&numChildren, &x, &y, &z, &pitch, &yaw, &roll,
&pivotx, &pivoty, &pivotz, name);
rootHierNode_[num].flags_ = flags;
rootHierNode_[num].type_ = type;
&numChildren, &x, &y, &z, &pitch, &yaw, &roll, &pivotx, &pivoty, &pivotz, name);
_rootHierNode[num]._flags = flags;
_rootHierNode[num]._type = type;
if (mesh < 0)
rootHierNode_[num].mesh_ = NULL;
_rootHierNode[num]._mesh = NULL;
else
rootHierNode_[num].mesh_ = geosets_[0].meshes_ + mesh;
_rootHierNode[num]._mesh = _geosets[0]._meshes + mesh;
if (parent >= 0) {
rootHierNode_[num].parent_ = rootHierNode_ + parent;
rootHierNode_[num].depth_ = rootHierNode_[parent].depth_ + 1;
_rootHierNode[num]._parent = _rootHierNode + parent;
_rootHierNode[num]._depth = _rootHierNode[parent]._depth + 1;
} else {
rootHierNode_[num].parent_ = NULL;
rootHierNode_[num].depth_ = 0;
_rootHierNode[num]._parent = NULL;
_rootHierNode[num]._depth = 0;
}
if (child >= 0)
rootHierNode_[num].child_ = rootHierNode_ + child;
_rootHierNode[num]._child = _rootHierNode + child;
else
rootHierNode_[num].child_ = NULL;
_rootHierNode[num]._child = NULL;
if (sibling >= 0)
rootHierNode_[num].sibling_ = rootHierNode_ + sibling;
_rootHierNode[num]._sibling = _rootHierNode + sibling;
else
rootHierNode_[num].sibling_ = NULL;
rootHierNode_[num].numChildren_ = numChildren;
rootHierNode_[num].pos_ = Vector3d(x, y, z);
rootHierNode_[num].pitch_ = pitch;
rootHierNode_[num].yaw_ = yaw;
rootHierNode_[num].roll_ = roll;
rootHierNode_[num].pivot_ = Vector3d(pivotx, pivoty, pivotz);
rootHierNode_[num].meshVisible_ = true;
rootHierNode_[num].hierVisible_ = true;
rootHierNode_[num].totalWeight_ = 1;
_rootHierNode[num]._sibling = NULL;
_rootHierNode[num]._numChildren = numChildren;
_rootHierNode[num]._pos = Vector3d(x, y, z);
_rootHierNode[num]._pitch = pitch;
_rootHierNode[num]._yaw = yaw;
_rootHierNode[num]._roll = roll;
_rootHierNode[num]._pivot = Vector3d(pivotx, pivoty, pivotz);
_rootHierNode[num]._meshVisible = true;
_rootHierNode[num]._hierVisible = true;
_rootHierNode[num]._totalWeight = 1;
}
if (!ts.eof())
@ -310,90 +308,94 @@ void Model::loadText(TextSplitter &ts, const CMap &cmap) {
}
void Model::Geoset::loadText(TextSplitter &ts, ResPtr<Material> *materials) {
ts.scanString("meshes %d", 1, &numMeshes_);
meshes_ = new Mesh[numMeshes_];
for (int i = 0; i < numMeshes_; i++) {
ts.scanString("meshes %d", 1, &_numMeshes);
_meshes = new Mesh[_numMeshes];
for (int i = 0; i < _numMeshes; i++) {
int num;
ts.scanString("mesh %d", 1, &num);
meshes_[num].loadText(ts, materials);
_meshes[num].loadText(ts, materials);
}
}
void Model::Mesh::loadText(TextSplitter &ts, ResPtr<Material> *materials) {
ts.scanString("name %32s", 1, name_);
ts.scanString("radius %f", 1, &radius_);
ts.scanString("name %32s", 1, _name);
ts.scanString("radius %f", 1, &_radius);
// In data001/rope_scale.3do, the shadow line is missing
if (std::sscanf(ts.currentLine(), "shadow %d", &shadow_) < 1) {
shadow_ = 0;
if (std::sscanf(ts.currentLine(), "shadow %d", &_shadow) < 1) {
_shadow = 0;
warning("Missing shadow directive in model\n");
} else
ts.nextLine();
ts.scanString("geometrymode %d", 1, &geometryMode_);
ts.scanString("lightingmode %d", 1, &lightingMode_);
ts.scanString("texturemode %d", 1, &textureMode_);
ts.scanString("vertices %d", 1, &numVertices_);
vertices_ = new float[3 * numVertices_];
verticesI_ = new float[numVertices_];
vertNormals_ = new float[3 * numVertices_];
ts.scanString("geometrymode %d", 1, &_geometryMode);
ts.scanString("lightingmode %d", 1, &_lightingMode);
ts.scanString("texturemode %d", 1, &_textureMode);
ts.scanString("vertices %d", 1, &_numVertices);
_vertices = new float[3 * _numVertices];
_verticesI = new float[_numVertices];
_vertNormals = new float[3 * _numVertices];
for (int i = 0; i < numVertices_; i++) {
for (int i = 0; i < _numVertices; i++) {
int num;
float x, y, z, ival;
ts.scanString(" %d: %f %f %f %f", 5, &num, &x, &y, &z, &ival);
vertices_[3 * num] = x;
vertices_[3 * num + 1] = y;
vertices_[3 * num + 2] = z;
verticesI_[num] = ival;
_vertices[3 * num] = x;
_vertices[3 * num + 1] = y;
_vertices[3 * num + 2] = z;
_verticesI[num] = ival;
}
ts.scanString("texture vertices %d", 1, &numTextureVerts_);
textureVerts_ = new float[2 * numTextureVerts_];
ts.scanString("texture vertices %d", 1, &_numTextureVerts);
_textureVerts = new float[2 * _numTextureVerts];
for (int i = 0; i < numTextureVerts_; i++) {
for (int i = 0; i < _numTextureVerts; i++) {
int num;
float x, y;
ts.scanString(" %d: %f %f", 3, &num, &x, &y);
textureVerts_[2 * num] = x;
textureVerts_[2 * num + 1] = y;
_textureVerts[2 * num] = x;
_textureVerts[2 * num + 1] = y;
}
ts.expectString("vertex normals");
for (int i = 0; i < numVertices_; i++) {
for (int i = 0; i < _numVertices; i++) {
int num;
float x, y, z;
ts.scanString(" %d: %f %f %f", 4, &num, &x, &y, &z);
vertNormals_[3 * num] = x;
vertNormals_[3 * num + 1] = y;
vertNormals_[3 * num + 2] = z;
_vertNormals[3 * num] = x;
_vertNormals[3 * num + 1] = y;
_vertNormals[3 * num + 2] = z;
}
ts.scanString("faces %d", 1, &numFaces_);
faces_ = new Face[numFaces_];
for (int i = 0; i < numFaces_; i++) {
ts.scanString("faces %d", 1, &_numFaces);
_faces = new Face[_numFaces];
for (int i = 0; i < _numFaces; i++) {
int num, material, type, geo, light, tex, verts;
float extralight;
int readlen;
if (ts.eof())
error("Expected face data, got EOF\n");
if (std::sscanf(ts.currentLine(), " %d: %d %i %d %d %d %f %d%n",
&num, &material, &type, &geo, &light, &tex, &extralight,
&verts, &readlen) < 8)
error("Expected face data, got `%s'\n", ts.currentLine());
faces_[num].material_ = materials[material];
faces_[num].type_ = type;
faces_[num].geo_ = geo;
faces_[num].light_ = light;
faces_[num].tex_ = tex;
faces_[num].extraLight_ = extralight;
faces_[num].numVertices_ = verts;
faces_[num].vertices_ = new int[verts];
faces_[num].texVertices_ = new int[verts];
&num, &material, &type, &geo, &light, &tex, &extralight, &verts, &readlen) < 8)
error("Expected face data, got `%s'\n", ts.currentLine());
_faces[num]._material = materials[material];
_faces[num]._type = type;
_faces[num]._geo = geo;
_faces[num]._light = light;
_faces[num]._tex = tex;
_faces[num]._extraLight = extralight;
_faces[num]._numVertices = verts;
_faces[num]._vertices = new int[verts];
_faces[num]._texVertices = new int[verts];
for (int j = 0; j < verts; j++) {
int readlen2;
if (std::sscanf(ts.currentLine() + readlen, " %d, %d%n",
faces_[num].vertices_ + j, faces_[num].texVertices_ + j, &readlen2) < 2)
error("Could not read vertex indices in line `%s'\n",
_faces[num]._vertices + j, _faces[num]._texVertices + j, &readlen2) < 2)
error("Could not read vertex indices in line `%s'\n",
ts.currentLine());
readlen += readlen2;
}
@ -401,11 +403,11 @@ void Model::Mesh::loadText(TextSplitter &ts, ResPtr<Material> *materials) {
}
ts.expectString("face normals");
for (int i = 0; i < numFaces_; i++) {
for (int i = 0; i < _numFaces; i++) {
int num;
float x, y, z;
ts.scanString(" %d: %f %f %f", 4, &num, &x, &y, &z);
faces_[num].normal_ = Vector3d(x, y, z);
_faces[num]._normal = Vector3d(x, y, z);
}
}
@ -414,48 +416,48 @@ void Model::HierNode::draw() const {
}
void Model::HierNode::addChild(HierNode *child) {
HierNode **childPos = &child_;
HierNode **childPos = &_child;
while (*childPos != NULL)
childPos = &(*childPos)->sibling_;
childPos = &(*childPos)->_sibling;
*childPos = child;
child->parent_ = this;
child->_parent = this;
}
void Model::HierNode::removeChild(HierNode *child) {
HierNode **childPos = &child_;
HierNode **childPos = &_child;
while (*childPos != NULL && *childPos != child)
childPos = &(*childPos)->sibling_;
childPos = &(*childPos)->_sibling;
if (*childPos != NULL) {
*childPos = child->sibling_;
child->parent_ = NULL;
*childPos = child->_sibling;
child->_parent = NULL;
}
}
void Model::HierNode::setMatrix(Matrix4 matrix) {
matrix_ = matrix;
_matrix = matrix;
}
void Model::HierNode::update() {
localMatrix_.pos_.set(animPos_.x() / totalWeight_, animPos_.y() / totalWeight_, animPos_.z() / totalWeight_);
localMatrix_.rot_.buildFromPitchYawRoll(animPitch_ / totalWeight_, animYaw_ / totalWeight_, animRoll_ / totalWeight_);
_localMatrix._pos.set(_animPos.x() / _totalWeight, _animPos.y() / _totalWeight, _animPos.z() / _totalWeight);
_localMatrix._rot.buildFromPitchYawRoll(_animPitch / _totalWeight, _animYaw / _totalWeight, _animRoll / _totalWeight);
matrix_ *= localMatrix_;
_matrix *= _localMatrix;
pivotMatrix = matrix_;
_pivotMatrix = _matrix;
pivotMatrix.translate( pivot_.x(), pivot_.y(), pivot_.z() );
_pivotMatrix.translate(_pivot.x(), _pivot.y(), _pivot.z() );
g_driver->updateHierachyNode(this);
}
void Model::Mesh::draw() const {
for (int i = 0; i < numFaces_; i++)
faces_[i].draw(vertices_, vertNormals_, textureVerts_);
for (int i = 0; i < _numFaces; i++)
_faces[i].draw(_vertices, _vertNormals, _textureVerts);
g_driver->drawModel(this);
}
void Model::Face::draw(float *vertices, float *vertNormals, float *textureVerts) const {
material_->select();
_material->select();
g_driver->drawModelFace(this, vertices, vertNormals, textureVerts);
}

86
model.h
View File

@ -48,24 +48,24 @@ public:
void setMatrix(Matrix4 matrix);
void update();
char name_[64];
Mesh *mesh_;
int flags_, type_;
int depth_, numChildren_;
HierNode *parent_, *child_, *sibling_;
Vector3d pos_, pivot_;
float pitch_, yaw_, roll_;
Vector3d animPos_;
float animPitch_, animYaw_, animRoll_;
bool meshVisible_, hierVisible_;
int priority_, totalWeight_;
Matrix4 matrix_;
Matrix4 localMatrix_;
Matrix4 pivotMatrix;
char _name[64];
Mesh *_mesh;
int _flags, _type;
int _depth, _numChildren;
HierNode *_parent, *_child, *_sibling;
Vector3d _pos, _pivot;
float _pitch, _yaw, _roll;
Vector3d _animPos;
float _animPitch, _animYaw, _animRoll;
bool _meshVisible, _hierVisible;
int _priority, _totalWeight;
Matrix4 _matrix;
Matrix4 _localMatrix;
Matrix4 _pivotMatrix;
};
HierNode *copyHierarchy();
int numNodes() const { return numHierNodes_; }
int numNodes() const { return _numHierNodes; }
//private:
struct Face {
@ -73,12 +73,12 @@ public:
void draw(float *vertices, float *vertNormals, float *textureVerts) const;
~Face();
Material *material_;
int type_, geo_, light_, tex_;
float extraLight_;
int numVertices_;
int *vertices_, *texVertices_;
Vector3d normal_;
Material *_material;
int _type, _geo, _light, _tex;
float _extraLight;
int _numVertices;
int *_vertices, *_texVertices;
Vector3d _normal;
};
struct Mesh {
@ -88,21 +88,21 @@ public:
void update();
~Mesh();
char name_[32];
float radius_;
int shadow_, geometryMode_, lightingMode_, textureMode_;
char _name[32];
float _radius;
int _shadow, _geometryMode, _lightingMode, _textureMode;
int numVertices_;
float *vertices_; // sets of 3
float *verticesI_;
float *vertNormals_; // sets of 3
int _numVertices;
float *_vertices; // sets of 3
float *_verticesI;
float *_vertNormals; // sets of 3
int numTextureVerts_;
float *textureVerts_; // sets of 2
int _numTextureVerts;
float *_textureVerts; // sets of 2
int numFaces_;
Face *faces_;
Matrix4 matrix_;
int _numFaces;
Face *_faces;
Matrix4 _matrix;
};
struct Geoset {
@ -110,18 +110,18 @@ public:
void loadText(TextSplitter &ts, ResPtr<Material> *materials);
~Geoset();
int numMeshes_;
Mesh *meshes_;
int _numMeshes;
Mesh *_meshes;
};
int numMaterials_;
ResPtr<Material> *materials_;
Vector3d insertOffset_;
int numGeosets_;
Geoset *geosets_;
float radius_;
int numHierNodes_;
HierNode *rootHierNode_;
int _numMaterials;
ResPtr<Material> *_materials;
Vector3d _insertOffset;
int _numGeosets;
Geoset *_geosets;
float _radius;
int _numHierNodes;
HierNode *_rootHierNode;
};
#endif

View File

@ -1,17 +1,15 @@
#include "objectstate.h"
ObjectState::ObjectState(int setupID, ObjectState::Position pos,
const char *bitmap, const char *zbitmap,
bool visible) :
setupID_(setupID), pos_(pos) {
bitmap_ = ResourceLoader::instance()->loadBitmap(bitmap);
ObjectState::ObjectState(int setupID, ObjectState::Position pos, const char *bitmap, const char *zbitmap, bool visible) :
_setupID(setupID), _pos(pos) {
_bitmap = ResourceLoader::instance()->loadBitmap(bitmap);
if (zbitmap)
zbitmap_ = ResourceLoader::instance()->loadBitmap(zbitmap);
_zbitmap = ResourceLoader::instance()->loadBitmap(zbitmap);
int initialImage = 0;
if (visible)
initialImage = 1;
bitmap_->setNumber(initialImage);
if (zbitmap_)
zbitmap_->setNumber(initialImage);
_bitmap->setNumber(initialImage);
if (_zbitmap)
_zbitmap->setNumber(initialImage);
}

View File

@ -16,32 +16,28 @@ class ObjectState {
OBJSTATE_STATE = 3
};
ObjectState(int setupID, ObjectState::Position pos,
const char *bitmap, const char *zbitmap,
bool visible);
int setupID() const { return setupID_; }
Position pos() const { return pos_; }
ObjectState(int setupID, ObjectState::Position pos, const char *bitmap, const char *zbitmap, bool visible);
int setupID() const { return _setupID; }
Position pos() const { return _pos; }
const char *bitmapFilename() const {
return bitmap_->filename();
return _bitmap->filename();
}
void setNumber(int val) {
bitmap_->setNumber(val);
if (zbitmap_)
zbitmap_->setNumber(val);
_bitmap->setNumber(val);
if (_zbitmap)
_zbitmap->setNumber(val);
}
void draw() {
bitmap_->draw();
if (zbitmap_)
zbitmap_->draw();
_bitmap->draw();
if (_zbitmap)
_zbitmap->draw();
}
private:
int setupID_;
Position pos_;
ResPtr<Bitmap> bitmap_, zbitmap_;
int _setupID;
Position _pos;
ResPtr<Bitmap> _bitmap, _zbitmap;
};
#endif

View File

@ -20,7 +20,7 @@
#include "debug.h"
#include <cstdlib>
Registry::Registry() : dirty_(false) {
Registry::Registry() : _dirty(false) {
#ifdef WIN32
std::string filename = "residual.ini";
#else
@ -38,24 +38,24 @@ Registry::Registry() : dirty_(false) {
if (equals != NULL) {
std::string key = std::string(line, equals - line);
std::string val = std::string(equals + 1);
settings_[key] = val;
_settings[key] = val;
}
}
std::fclose(f);
}
}
Registry *Registry::instance_ = NULL;
Registry *Registry::_instance = NULL;
Registry *Registry::instance() {
if (instance_ == NULL)
instance_ = new Registry;
return instance_;
if (_instance == NULL)
_instance = new Registry;
return _instance;
}
const char *Registry::get(const char *key) const {
group::const_iterator i = settings_.find(key);
if (i == settings_.end())
group::const_iterator i = _settings.find(key);
if (i == _settings.end())
return NULL;
else
return i->second.c_str();
@ -67,12 +67,12 @@ void Registry::set(const char *key, const char *val) {
if (strstr(key, "GrimLastSet") || strstr(key, "GrimMannyState"))
return;
settings_[key] = val;
dirty_ = true;
_settings[key] = val;
_dirty = true;
}
void Registry::save() {
if (! dirty_)
if (!_dirty)
return;
#ifdef WIN32
@ -88,9 +88,9 @@ void Registry::save() {
return;
}
for (group::iterator i = settings_.begin(); i != settings_.end(); i++)
for (group::iterator i = _settings.begin(); i != _settings.end(); i++)
std::fprintf(f, "%s=%s\n", i->first.c_str(), i->second.c_str());
std::fclose(f);
dirty_ = false;
_dirty = false;
}

View File

@ -25,7 +25,7 @@ class Registry {
public:
static Registry *instance();
const char * get(const char *key) const;
const char *get(const char *key) const;
void set(const char *key, const char *val);
void save();
@ -33,11 +33,11 @@ private:
Registry();
~Registry() { }
static Registry *instance_;
static Registry *_instance;
typedef std::map<std::string, std::string> group;
group settings_;
bool dirty_;
group _settings;
bool _dirty;
};
#endif

View File

@ -36,7 +36,7 @@ static void makeLower(std::string& s) {
std::transform(s.begin(), s.end(), s.begin(), tolower);
}
ResourceLoader *ResourceLoader::instance_ = NULL;
ResourceLoader *ResourceLoader::_instance = NULL;
ResourceLoader::ResourceLoader() {
const char *directory = Registry::instance()->get("DataDir");
@ -69,9 +69,9 @@ ResourceLoader::ResourceLoader() {
lab_counter++;
if (l->isOpen())
if (strstr(find_file_data.cFileName, "005"))
labs_.push_front(l);
_labs.push_front(l);
else
labs_.push_back(l);
_labs.push_back(l);
else
delete l;
}
@ -100,11 +100,11 @@ ResourceLoader::ResourceLoader() {
#endif
if (lab_counter == 0)
error("Cannot find any resource files in %s - check configuration file", dir_str.c_str());
error("Cannot find any resource files in %s - check configuration file", dir_str.c_str());
}
const Lab *ResourceLoader::findFile(const char *filename) const {
for (LabList::const_iterator i = labs_.begin(); i != labs_.end(); i++)
for (LabList::const_iterator i = _labs.begin(); i != _labs.end(); i++)
if ((*i)->fileExists(filename))
return *i;
return NULL;
@ -142,8 +142,8 @@ int ResourceLoader::fileLength(const char *filename) const {
Bitmap *ResourceLoader::loadBitmap(const char *filename) {
std::string fname = filename;
makeLower(fname);
cache_type::iterator i = cache_.find(fname);
if (i != cache_.end()) {
cache_type::iterator i = _cache.find(fname);
if (i != _cache.end()) {
return dynamic_cast<Bitmap *>(i->second);
}
@ -155,15 +155,16 @@ Bitmap *ResourceLoader::loadBitmap(const char *filename) {
Bitmap *result = new Bitmap(filename, b->data(), b->len());
delete b;
cache_[fname] = result;
_cache[fname] = result;
return result;
}
CMap *ResourceLoader::loadColormap(const char *filename) {
std::string fname = filename;
makeLower(fname);
cache_type::iterator i = cache_.find(fname);
if (i != cache_.end()) {
cache_type::iterator i = _cache.find(fname);
if (i != _cache.end()) {
return dynamic_cast<CMap *>(i->second);
}
@ -172,7 +173,7 @@ CMap *ResourceLoader::loadColormap(const char *filename) {
error("Could not find colormap %s\n", filename);
CMap *result = new CMap(filename, b->data(), b->len());
delete b;
cache_[fname] = result;
_cache[fname] = result;
return result;
}
@ -190,8 +191,8 @@ Costume *ResourceLoader::loadCostume(const char *filename, Costume *prevCost) {
KeyframeAnim *ResourceLoader::loadKeyframe(const char *filename) {
std::string fname = filename;
makeLower(fname);
cache_type::iterator i = cache_.find(fname);
if (i != cache_.end()) {
cache_type::iterator i = _cache.find(fname);
if (i != _cache.end()) {
return dynamic_cast<KeyframeAnim *>(i->second);
}
@ -200,7 +201,7 @@ KeyframeAnim *ResourceLoader::loadKeyframe(const char *filename) {
error("Could not find keyframe file %s\n", filename);
KeyframeAnim *result = new KeyframeAnim(filename, b->data(), b->len());
delete b;
cache_[fname] = result;
_cache[fname] = result;
return result;
}
@ -209,8 +210,8 @@ LipSynch *ResourceLoader::loadLipSynch(const char *filename) {
LipSynch *result;
makeLower(fname);
cache_type::iterator i = cache_.find(fname);
if (i != cache_.end()) {
cache_type::iterator i = _cache.find(fname);
if (i != _cache.end()) {
return dynamic_cast<LipSynch *>(i->second);
}
@ -221,7 +222,7 @@ LipSynch *ResourceLoader::loadLipSynch(const char *filename) {
} else {
result = new LipSynch(filename, b->data(), b->len());
delete b;
cache_[fname] = result;
_cache[fname] = result;
}
return result;
@ -230,8 +231,8 @@ LipSynch *ResourceLoader::loadLipSynch(const char *filename) {
Material *ResourceLoader::loadMaterial(const char *filename, const CMap &c) {
std::string fname = filename;
makeLower(fname);
cache_type::iterator i = cache_.find(fname);
if (i != cache_.end()) {
cache_type::iterator i = _cache.find(fname);
if (i != _cache.end()) {
return dynamic_cast<Material *>(i->second);
}
@ -240,15 +241,15 @@ Material *ResourceLoader::loadMaterial(const char *filename, const CMap &c) {
error("Could not find material %s\n", filename);
Material *result = new Material(filename, b->data(), b->len(), c);
delete b;
cache_[fname] = result;
_cache[fname] = result;
return result;
}
Model *ResourceLoader::loadModel(const char *filename, const CMap &c) {
std::string fname = filename;
makeLower(fname);
cache_type::iterator i = cache_.find(fname);
if (i != cache_.end()) {
cache_type::iterator i = _cache.find(fname);
if (i != _cache.end()) {
return dynamic_cast<Model *>(i->second);
}
@ -257,15 +258,15 @@ Model *ResourceLoader::loadModel(const char *filename, const CMap &c) {
error("Could not find model %s\n", filename);
Model *result = new Model(filename, b->data(), b->len(), c);
delete b;
cache_[fname] = result;
_cache[fname] = result;
return result;
}
Sound *ResourceLoader::loadSound(const char *filename) {
std::string fname = filename;
makeLower(fname);
cache_type::iterator i = cache_.find(fname);
if (i != cache_.end()) {
cache_type::iterator i = _cache.find(fname);
if (i != _cache.end()) {
return dynamic_cast<Sound *>(i->second);
}
@ -274,14 +275,14 @@ Sound *ResourceLoader::loadSound(const char *filename) {
return NULL;
Sound *result = new Sound(filename, b->data(), b->len());
delete b;
cache_[fname] = result;
_cache[fname] = result;
return result;
}
void ResourceLoader::uncache(const char *filename) {
std::string fname = filename;
makeLower(fname);
cache_type::iterator i = cache_.find(fname);
if (i != cache_.end())
cache_.erase(i);
cache_type::iterator i = _cache.find(fname);
if (i != _cache.end())
_cache.erase(i);
}

View File

@ -35,52 +35,52 @@ class LipSynch;
class Resource {
public:
Resource(const char *filename) :
fname_(filename), ref_(0), luaRef_(false) { }
Resource(const Resource &r) : fname_(r.fname_), ref_(0), luaRef_(false) {}
_fname(filename), _ref(0), _luaRef(false) { }
Resource(const Resource &r) : _fname(r._fname), _ref(0), _luaRef(false) {}
virtual ~Resource() { }
void ref() { ref_++; }
void ref() { _ref++; }
void deref();
const char *filename() const { return fname_.c_str(); }
const char *filename() const { return _fname.c_str(); }
void luaRef() { if (! luaRef_) { ref(); luaRef_ = true; } }
void luaGc() { if (luaRef_) { luaRef_ = false; deref(); } }
void luaRef() { if (!_luaRef) { ref(); _luaRef = true; } }
void luaGc() { if (_luaRef) { _luaRef = false; deref(); } }
private:
std::string fname_;
int ref_;
bool luaRef_;
std::string _fname;
int _ref;
bool _luaRef;
};
template <class T>
class ResPtr {
public:
ResPtr() { ptr_ = NULL; }
ResPtr(const ResPtr &p) { ptr_ = p.ptr_; if (ptr_ != NULL) ptr_->ref(); }
ResPtr(T* ptr) { ptr_ = ptr; if (ptr_ != NULL) ptr_->ref(); }
operator T*() { return ptr_; }
operator const T*() const { return ptr_; }
T& operator *() { return *ptr_; }
const T& operator *() const { return *ptr_; }
T* operator ->() { return ptr_; }
const T* operator ->() const { return ptr_; }
ResPtr() { _ptr = NULL; }
ResPtr(const ResPtr &p) { _ptr = p._ptr; if (_ptr != NULL) _ptr->ref(); }
ResPtr(T* ptr) { _ptr = ptr; if (_ptr != NULL) _ptr->ref(); }
operator T*() { return _ptr; }
operator const T*() const { return _ptr; }
T& operator *() { return *_ptr; }
const T& operator *() const { return *_ptr; }
T* operator ->() { return _ptr; }
const T* operator ->() const { return _ptr; }
ResPtr& operator =(T* ptr) {
if (ptr_ == ptr) return *this;
if (ptr_ != NULL) ptr_->deref();
ptr_ = ptr;
if (ptr_ != NULL) ptr_->ref();
if (_ptr == ptr) return *this;
if (_ptr != NULL) _ptr->deref();
_ptr = ptr;
if (_ptr != NULL) _ptr->ref();
return *this;
}
ResPtr& operator =(const ResPtr& p) {
if (this == &p || ptr_ == p.ptr_) return *this;
if (ptr_ != NULL) ptr_->deref();
ptr_ = p.ptr_;
if (ptr_ != NULL) ptr_->ref();
if (this == &p || _ptr == p._ptr) return *this;
if (_ptr != NULL) _ptr->deref();
_ptr = p._ptr;
if (_ptr != NULL) _ptr->ref();
return *this;
}
~ResPtr() { if (ptr_ != NULL) ptr_->deref(); }
~ResPtr() { if (_ptr != NULL) _ptr->deref(); }
private:
T* ptr_;
T* _ptr;
};
class ResourceLoader {
@ -91,9 +91,9 @@ public:
int fileLength(const char *filename) const;
static ResourceLoader *instance() {
if (instance_ == NULL)
instance_ = new ResourceLoader;
return instance_;
if (_instance == NULL)
_instance = new ResourceLoader;
return _instance;
}
Bitmap *loadBitmap(const char *fname);
@ -111,23 +111,23 @@ private:
ResourceLoader(const ResourceLoader &);
~ResourceLoader();
static ResourceLoader *instance_;
static ResourceLoader *_instance;
typedef std::list<Lab *> LabList;
LabList labs_;
LabList _labs;
const Lab *findFile(const char *filename) const;
typedef std::map<std::string, Resource *> cache_type;
cache_type cache_;
cache_type _cache;
// Shut up pointless g++ warning
friend class dummy;
};
inline void Resource::deref() {
if (--ref_ == 0) {
ResourceLoader::instance()->uncache(fname_.c_str());
if (--_ref == 0) {
ResourceLoader::instance()->uncache(_fname.c_str());
delete this;
}
}

133
scene.cpp
View File

@ -29,39 +29,39 @@
#include "driver_gl.h"
Scene::Scene(const char *name, const char *buf, int len) :
name_(name) {
_name(name) {
TextSplitter ts(buf, len);
char tempBuf[256];
ts.expectString("section: colormaps");
ts.scanString(" numcolormaps %d", 1, &numCmaps_);
cmaps_ = new ResPtr<CMap>[numCmaps_];
ts.scanString(" numcolormaps %d", 1, &_numCmaps);
_cmaps = new ResPtr<CMap>[_numCmaps];
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);
cmaps_[i] = ResourceLoader::instance()->loadColormap(cmap_name);
_cmaps[i] = ResourceLoader::instance()->loadColormap(cmap_name);
}
ts.expectString("section: setups");
ts.scanString(" numsetups %d", 1, &numSetups_);
setups_ = new Setup[numSetups_];
for (int i = 0; i < numSetups_; i++)
setups_[i].load(ts);
currSetup_ = setups_;
ts.scanString(" numsetups %d", 1, &_numSetups);
_setups = new Setup[_numSetups];
for (int i = 0; i < _numSetups; i++)
_setups[i].load(ts);
_currSetup = _setups;
numSectors_ = -1;
numLights_ = -1;
lights_ = NULL;
sectors_ = NULL;
_numSectors = -1;
_numLights = -1;
_lights = NULL;
_sectors = NULL;
// Lights are optional
if (ts.eof())
return;
ts.expectString("section: lights");
ts.scanString(" numlights %d", 1, &numLights_);
lights_ = new Light[numLights_];
for (int i = 0; i < numLights_; i++)
lights_[i].load(ts);
ts.scanString(" numlights %d", 1, &_numLights);
_lights = new Light[_numLights];
for (int i = 0; i < _numLights; i++)
_lights[i].load(ts);
// Calculate the number of sectors
ts.expectString("section: sectors");
@ -76,25 +76,24 @@ Scene::Scene(const char *name, const char *buf, int len) :
strcpy(tempBuf, "");
}
ts.scanString(" id %d", 1, &numSectors_);
numSectors_++;
sectors_ = new Sector[numSectors_];
ts.scanString(" id %d", 1, &_numSectors);
_numSectors++;
_sectors = new Sector[_numSectors];
// FIXME: This would be nicer if we could rewind the textsplitter
// stream
sectors_[0].load0(ts, tempBuf, numSectors_);
for (int i = 1; i < numSectors_; i++)
sectors_[i].load(ts);
_sectors[0].load0(ts, tempBuf, _numSectors);
for (int i = 1; i < _numSectors; i++)
_sectors[i].load(ts);
}
Scene::~Scene() {
delete [] cmaps_;
delete [] setups_;
if (lights_)
delete [] lights_;
if (sectors_)
delete [] sectors_;
for (StateList::iterator i = states_.begin();
i != states_.end(); i++)
delete [] _cmaps;
delete [] _setups;
if (_lights)
delete [] _lights;
if (_sectors)
delete [] _sectors;
for (StateList::iterator i = _states.begin(); i != _states.end(); i++)
delete (*i);
}
@ -102,26 +101,25 @@ void Scene::Setup::load(TextSplitter &ts) {
char buf[256];
ts.scanString(" setup %256s", 1, buf);
name_ = buf;
_name = buf;
ts.scanString(" background %256s", 1, buf);
bkgnd_bm_ = ResourceLoader::instance()->loadBitmap(buf);
_bkgnd_bm = ResourceLoader::instance()->loadBitmap(buf);
// ZBuffer is optional
if (!ts.checkString("zbuffer")) {
bkgnd_zbm_ = NULL;
_bkgnd_zbm = NULL;
} else {
ts.scanString(" zbuffer %256s", 1, buf);
bkgnd_zbm_ = ResourceLoader::instance()->loadBitmap(buf);
_bkgnd_zbm = ResourceLoader::instance()->loadBitmap(buf);
}
ts.scanString(" position %f %f %f", 3, &pos_.x(), &pos_.y(), &pos_.z());
ts.scanString(" interest %f %f %f", 3, &interest_.x(), &interest_.y(),
&interest_.z());
ts.scanString(" roll %f", 1, &roll_);
ts.scanString(" fov %f", 1, &fov_);
ts.scanString(" nclip %f", 1, &nclip_);
ts.scanString(" fclip %f", 1, &fclip_);
ts.scanString(" position %f %f %f", 3, &_pos.x(), &_pos.y(), &_pos.z());
ts.scanString(" interest %f %f %f", 3, &_interest.x(), &_interest.y(), &_interest.z());
ts.scanString(" roll %f", 1, &_roll);
ts.scanString(" fov %f", 1, &_fov);
ts.scanString(" nclip %f", 1, &_nclip);
ts.scanString(" fclip %f", 1, &_fclip);
}
void Scene::Light::load(TextSplitter &ts) {
@ -134,17 +132,17 @@ void Scene::Light::load(TextSplitter &ts) {
ts.nextLine();
strcpy(buf, "");
}
name_ = buf;
_name = buf;
ts.scanString(" type %256s", 1, buf);
type_ = buf;
_type = buf;
ts.scanString(" position %f %f %f", 3, &pos_.x(), &pos_.y(), &pos_.z());
ts.scanString(" direction %f %f %f", 3, &dir_.x(), &dir_.y(), &dir_.z());
ts.scanString(" intensity %f", 1, &intensity_);
ts.scanString(" umbraangle %f", 1, &umbraangle_);
ts.scanString(" penumbraangle %f", 1, &penumbraangle_);
ts.scanString(" color %d %d %d", 3, &color_.red(), &color_.green(), &color_.blue());
ts.scanString(" position %f %f %f", 3, &_pos.x(), &_pos.y(), &_pos.z());
ts.scanString(" direction %f %f %f", 3, &_dir.x(), &_dir.y(), &_dir.z());
ts.scanString(" intensity %f", 1, &_intensity);
ts.scanString(" umbraangle %f", 1, &_umbraangle);
ts.scanString(" penumbraangle %f", 1, &_penumbraangle);
ts.scanString(" color %d %d %d", 3, &_color.red(), &_color.green(), &_color.blue());
}
void Scene::Setup::setupCamera() const {
@ -156,32 +154,32 @@ void Scene::Setup::setupCamera() const {
// are important at some point, we'll need to modify the
// zbuffer transformation in bitmap.cpp to take nclip_ and
// fclip_ into account.
g_driver->setupCamera(fov_, 0.01f, 3276.8f, roll_);
g_driver->positionCamera(pos_, interest_);
g_driver->setupCamera(_fov, 0.01f, 3276.8f, _roll);
g_driver->positionCamera(_pos, _interest);
}
void Scene::setSetup(int num) {
currSetup_ = setups_ + num;
_currSetup = _setups + num;
if (! SCREENBLOCKS_GLOBAL)
if (!SCREENBLOCKS_GLOBAL)
return;
if(currSetup_->bkgnd_zbm_)
screenBlocksInit( currSetup_->bkgnd_zbm_->getData() );
if (_currSetup->_bkgnd_zbm)
screenBlocksInit(_currSetup->_bkgnd_zbm->getData() );
else
screenBlocksInitEmpty();
}
void Scene::drawBitmaps(ObjectState::Position stage) {
for (StateList::iterator i = states_.begin(); i != states_.end();
i++) {
if ((*i)->pos() == stage && currSetup_ == setups_ + (*i)->setupID())
for (StateList::iterator i = _states.begin(); i != _states.end(); i++) {
if ((*i)->pos() == stage && _currSetup == _setups + (*i)->setupID())
(*i)->draw();
}
}
Sector *Scene::findPointSector(Vector3d p, int flags) {
for (int i = 0; i < numSectors_; i++) {
Sector *sector = sectors_ + i;
for (int i = 0; i < _numSectors; i++) {
Sector *sector = _sectors + i;
if ((sector->type() & flags) && sector->visible() &&
sector->isPointInSector(p))
return sector;
@ -194,10 +192,9 @@ void Scene::findClosestSector(Vector3d p, Sector **sect, Vector3d *closestPt) {
Vector3d resultPt = p;
float minDist;
for (int i = 0; i < numSectors_; i++) {
Sector *sector = sectors_ + i;
if ((sector->type() & 0x1000) == 0 ||
! sector->visible())
for (int i = 0; i < _numSectors; i++) {
Sector *sector = _sectors + i;
if ((sector->type() & 0x1000) == 0 || !sector->visible())
continue;
Vector3d closestPt = sector->closestPoint(p);
float thisDist = (closestPt - p).magnitude();
@ -210,13 +207,13 @@ void Scene::findClosestSector(Vector3d p, Sector **sect, Vector3d *closestPt) {
if (sect != NULL)
*sect = resultSect;
if (closestPt != NULL)
*closestPt = resultPt;
}
ObjectState *Scene::findState(const char *filename) {
for (StateList::iterator i = states_.begin(); i != states_.end();
i++) {
for (StateList::iterator i = _states.begin(); i != _states.end(); i++) {
if (strcmp((*i)->bitmapFilename(), filename) == 0)
return *i;
}

60
scene.h
View File

@ -39,30 +39,30 @@ public:
~Scene();
void drawBackground() const {
if (currSetup_->bkgnd_zbm_ != NULL) // Some screens have no zbuffer mask (eg, Alley)
currSetup_->bkgnd_zbm_->draw();
if (_currSetup->_bkgnd_zbm != NULL) // Some screens have no zbuffer mask (eg, Alley)
_currSetup->_bkgnd_zbm->draw();
if (currSetup_->bkgnd_bm_ == NULL) {
error("Null background for setup %s in %s", currSetup_->name_.c_str(), name_.c_str());
if (_currSetup->_bkgnd_bm == NULL) {
error("Null background for setup %s in %s", _currSetup->_name.c_str(), _name.c_str());
return;
}
currSetup_->bkgnd_bm_->draw();
_currSetup->_bkgnd_bm->draw();
}
void drawBitmaps(ObjectState::Position stage);
void setupCamera() {
currSetup_->setupCamera();
_currSetup->setupCamera();
}
const char *name() const { return name_.c_str(); }
const char *name() const { return _name.c_str(); }
void setSetup(int num);
int setup() const { return currSetup_ - setups_; }
int setup() const { return _currSetup - _setups; }
// Sector access functions
int getSectorCount() { return numSectors_; }
int getSectorCount() { return _numSectors; }
Sector *getSectorBase(int id) {
if ((numSectors_ >= 0) && (id < numSectors_))
return &sectors_[id];
if ((_numSectors >= 0) && (id < _numSectors))
return &_sectors[id];
else
return NULL;
}
@ -70,7 +70,7 @@ public:
void findClosestSector(Vector3d p, Sector **sect, Vector3d *closestPt);
void addObjectState(ObjectState *s) {
states_.push_back(s);
_states.push_back(s);
}
ObjectState *findState(const char *filename);
@ -78,32 +78,32 @@ private:
struct Setup { // Camera setup data
void load(TextSplitter &ts);
void setupCamera() const;
std::string name_;
ResPtr<Bitmap> bkgnd_bm_, bkgnd_zbm_;
Vector3d pos_, interest_;
float roll_, fov_, nclip_, fclip_;
std::string _name;
ResPtr<Bitmap> _bkgnd_bm, _bkgnd_zbm;
Vector3d _pos, _interest;
float _roll, _fov, _nclip, _fclip;
};
struct Light { // Scene lighting data
void load(TextSplitter &ts);
std::string name_;
std::string type_;
Vector3d pos_, dir_;
Color color_;
float intensity_, umbraangle_, penumbraangle_;
std::string _name;
std::string _type;
Vector3d _pos, _dir;
Color _color;
float _intensity, _umbraangle, _penumbraangle;
};
std::string name_;
int numCmaps_;
ResPtr<CMap> *cmaps_;
int numSetups_, numLights_, numSectors_;
Sector *sectors_;
Light *lights_;
Setup *setups_;
Setup *currSetup_;
std::string _name;
int _numCmaps;
ResPtr<CMap> *_cmaps;
int _numSetups, _numLights, _numSectors;
Sector *_sectors;
Light *_lights;
Setup *_setups;
Setup *_currSetup;
typedef std::list<ObjectState*> StateList;
StateList states_;
StateList _states;
};
#endif

View File

@ -23,11 +23,8 @@ unsigned short int dataTemp[640 * 480];
screenBlockDataStruct screenBlockData[NUM_SCREEN_BLOCK_WIDTH][NUM_SCREEN_BLOCK_HEIGHT];
void screenBlocksReset() {
int i;
int j;
for(i = 0; i < NUM_SCREEN_BLOCK_WIDTH; i++) {
for(j = 0; j < NUM_SCREEN_BLOCK_HEIGHT; j++) {
for (int i = 0; i < NUM_SCREEN_BLOCK_WIDTH; i++) {
for (int j = 0; j < NUM_SCREEN_BLOCK_HEIGHT; j++) {
screenBlockData[i][j].isDirty = false;
}
}
@ -35,16 +32,12 @@ void screenBlocksReset() {
float getZbufferBlockDepth(char *zbuffer, int x, int y) {
unsigned short int buffer[SCREEN_BLOCK_WIDTH * SCREEN_BLOCK_HEIGHT];
char *readPtr;
char *writePtr;
char *writePtr = (char *)buffer;
int i;
int j;
writePtr = (char *)buffer;
for(i = 0; i < 16; i++) {
readPtr = zbuffer + (y * 16 + i) * 640 + (x * 16);
for(j = 0; j < 16; j++) {
for (i = 0; i < 16; i++) {
char *readPtr = zbuffer + (y * 16 + i) * 640 + (x * 16);
for (int j = 0; j < 16; j++) {
*(writePtr++) = *(readPtr++);
*(writePtr++) = *(readPtr++);
}
@ -52,8 +45,8 @@ float getZbufferBlockDepth(char *zbuffer, int x, int y) {
unsigned short int bDepth = 0xFFFF;
for(i = 0; i < SCREEN_BLOCK_SIZE; i++ ) {
if(bDepth > buffer[i])
for (i = 0; i < SCREEN_BLOCK_SIZE; i++ ) {
if (bDepth > buffer[i])
bDepth = buffer[i];
}
@ -61,13 +54,10 @@ float getZbufferBlockDepth(char *zbuffer, int x, int y) {
}
void screenBlocksInit(char* zbuffer) {
int i;
int j;
memcpy(dataTemp, zbuffer, 640 * 480 * 2);
for(i = 0; i < NUM_SCREEN_BLOCK_WIDTH; i++) {
for(j = 0; j < NUM_SCREEN_BLOCK_HEIGHT; j++) {
for (int i = 0; i < NUM_SCREEN_BLOCK_WIDTH; i++) {
for(int j = 0; j < NUM_SCREEN_BLOCK_HEIGHT; j++) {
screenBlockData[i][j].isDirty = false;
screenBlockData[i][j].depth = getZbufferBlockDepth(zbuffer, i, j);
}
@ -75,11 +65,8 @@ void screenBlocksInit(char* zbuffer) {
}
void screenBlocksInitEmpty() {
int i;
int j;
for(i = 0; i < NUM_SCREEN_BLOCK_WIDTH; i++ ) {
for( j = 0; j < NUM_SCREEN_BLOCK_HEIGHT; j++ ) {
for (int i = 0; i < NUM_SCREEN_BLOCK_WIDTH; i++ ) {
for (int j = 0; j < NUM_SCREEN_BLOCK_HEIGHT; j++ ) {
screenBlockData[i][j].isDirty = false;
screenBlockData[i][j].depth = 1.f;
}
@ -89,32 +76,32 @@ void screenBlocksInitEmpty() {
void screenBlocksAddRectangle( int top, int right, int left, int bottom, float depth) {
// clip the rectange to the screen size
int tempHeight = bottom-top;
int tempHeight = bottom - top;
top = 480 - bottom;
bottom = top + tempHeight;
if(top < 0)
if (top < 0)
top = 0;
if(top >= SCREEN_HEIGHT)
if (top >= SCREEN_HEIGHT)
top = SCREEN_HEIGHT - 1;
if(bottom < 0)
if (bottom < 0)
bottom = 0;
if(bottom >= SCREEN_HEIGHT)
if (bottom >= SCREEN_HEIGHT)
bottom = SCREEN_HEIGHT - 1;
if(left < 0)
if (left < 0)
left = 0;
if(left >= SCREEN_WIDTH)
if (left >= SCREEN_WIDTH)
left = SCREEN_WIDTH - 1;
if(right < 0)
if (right < 0)
right = 0;
if(right >= SCREEN_WIDTH)
if (right >= SCREEN_WIDTH)
right = SCREEN_WIDTH - 1;
// exit in case of bad rectangle
if((left > right) || (top > bottom))
if ((left > right) || (top > bottom))
return;
int firstLeft;
@ -126,22 +113,19 @@ void screenBlocksAddRectangle( int top, int right, int left, int bottom, float d
firstTop = top /16;
width = (right - left) / 16;
if((right-left) % 16)
if ((right-left) % 16)
width++;
height = (bottom - top) / 16;
if((bottom - top) % 16)
if ((bottom - top) % 16)
height++;
// temp hack
width++;
height++;
int i;
int j;
for(i = firstLeft; i < firstLeft + width; i++) {
for(j = firstTop; j < firstTop + height; j++) {
for (int i = firstLeft; i < firstLeft + width; i++) {
for (int j = firstTop; j < firstTop + height; j++) {
if(screenBlockData[i][j].depth < depth)
screenBlockData[i][j].isDirty = true;
}
@ -149,9 +133,6 @@ void screenBlocksAddRectangle( int top, int right, int left, int bottom, float d
}
void screenBlocksDrawDebug() {
int i;
int j;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 640, 480, 0, 0, 1);
@ -159,14 +140,14 @@ void screenBlocksDrawDebug() {
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glColor4f( 1.f, 0.3f, 1.f, 0.4f );
glColor4f(1.f, 0.3f, 1.f, 0.4f);
glDisable(GL_TEXTURE_2D );
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for(i = 0; i < 40; i++) {
for(j = 0;j < 30; j++) {
for (int i = 0; i < 40; i++) {
for (int j = 0;j < 30; j++) {
if(screenBlockData[i][j].isDirty) {
glBegin(GL_QUADS);
glVertex2i(i * 16, j * 16);
@ -183,9 +164,6 @@ void screenBlocksDrawDebug() {
}
void screenBlocksBlitDirtyBlocks() {
int i;
int j;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 640, 480, 0, 0, 1);
@ -197,8 +175,8 @@ void screenBlocksBlitDirtyBlocks() {
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_TRUE);
for(j = 0;j < 30; j++) {
for(i = 0; i < 40; i++) {
for (int j = 0;j < 30; j++) {
for (int i = 0; i < 40; i++) {
if (screenBlockData[i][j].isDirty) {
int width = 1;
int start = i++;
@ -209,7 +187,7 @@ void screenBlocksBlitDirtyBlocks() {
}
for (int y = 0; y < 16; y++) {
glRasterPos2i(start * 16, j * 16 + y + 1);
glDrawPixels(16 * width, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, dataTemp+((j*16 +y) * 640)+(start*16));
glDrawPixels(16 * width, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, dataTemp + ((j * 16 + y) * 640)+(start * 16));
}
}
}

View File

@ -26,7 +26,7 @@
#define SCREEN_BLOCK_WIDTH 16
#define SCREEN_BLOCK_HEIGHT 16
#define SCREEN_BLOCK_SIZE (SCREEN_BLOCK_WIDTH*SCREEN_BLOCK_HEIGHT)
#define SCREEN_BLOCK_SIZE (SCREEN_BLOCK_WIDTH * SCREEN_BLOCK_HEIGHT)
// Yaz: warning, SCREEN_WIDTH must be divisible by SCREEN_BLOCK_WIDTH and SCREEN_HEIGHT by SCREEN_BLOCK_HEIGH
// maybe we should check it with the precompiler...
@ -41,9 +41,9 @@ struct screenBlockDataStruct {
};
void screenBlocksReset();
void screenBlocksInit(char* zbuffer);
void screenBlocksInit(char *zbuffer);
void screenBlocksInitEmpty();
void screenBlocksAddRectangle( int top, int right, int left, int bottom, float depth );
void screenBlocksAddRectangle(int top, int right, int left, int bottom, float depth);
void screenBlocksDrawDebug();
void screenBlocksBlitDirtyBlocks();

118
sound.cpp
View File

@ -249,12 +249,12 @@ static const imuseTableEntry grimMusicTable[] = {
{ 2399, "2399 - End Credits.IMC" }
};
Mixer *Mixer::instance_ = NULL;
Mixer *Mixer::_instance = NULL;
Mixer *Mixer::instance() {
if (instance_ == NULL)
instance_ = new Mixer;
return instance_;
if (_instance == NULL)
_instance = new Mixer;
return _instance;
}
void mixerCallback(void *userdata, int16 *stream, uint len) {
@ -265,7 +265,7 @@ void mixerCallback(void *userdata, int16 *stream, uint len) {
extern SoundMixer *g_mixer;
Mixer::Mixer() :
musicSound_(NULL), seqSound_(NULL){
_musicSound(NULL), _seqSound(NULL){
}
void Mixer::start() {
@ -276,27 +276,27 @@ void Mixer::start() {
void Mixer::playVoice(Sound *s) {
s->reset();
voiceSounds_.push_back(s);
_voiceSounds.push_back(s);
}
void Mixer::playSfx(Sound *s) {
s->reset();
sfxSounds_.push_back(s);
_sfxSounds.push_back(s);
}
void Mixer::stopSfx(Sound *s) {
for (sound_list::iterator i = sfxSounds_.begin(); i != sfxSounds_.end(); ) {
for (sound_list::iterator i = _sfxSounds.begin(); i != _sfxSounds.end(); ) {
if (*i == s)
i = sfxSounds_.erase(i);
i = _sfxSounds.erase(i);
else
i++;
}
}
void Mixer::stopVoice(Sound *s) {
for (sound_list::iterator i = voiceSounds_.begin(); i != voiceSounds_.end(); ) {
for (sound_list::iterator i = _voiceSounds.begin(); i != _voiceSounds.end(); ) {
if (*i == s)
i = voiceSounds_.erase(i);
i = _voiceSounds.erase(i);
else
i++;
}
@ -314,10 +314,8 @@ void Mixer::setImuseState(int state) {
if (state != 1000) {
imuseTableEntry key;
key.stateNum = state;
const imuseTableEntry *e = static_cast<imuseTableEntry *>
(std::bsearch(&key, grimMusicTable,
sizeof(grimMusicTable) / sizeof(grimMusicTable[0]),
sizeof(grimMusicTable[0]), compareStates));
const imuseTableEntry *e = static_cast<imuseTableEntry *>(std::bsearch(&key, grimMusicTable,
sizeof(grimMusicTable) / sizeof(grimMusicTable[0]), sizeof(grimMusicTable[0]), compareStates));
if (e == NULL) {
warning("Unknown IMuse state %d\n", state);
return;
@ -330,10 +328,10 @@ void Mixer::setImuseState(int state) {
}
}
if (newSound != musicSound_) {
if (newSound != _musicSound) {
if (newSound != NULL)
newSound->reset();
musicSound_ = newSound;
_musicSound = newSound;
}
}
@ -343,10 +341,8 @@ void Mixer::setImuseSeq(int state) {
if (state != 2000) {
imuseTableEntry key;
key.stateNum = state;
const imuseTableEntry *e = static_cast<imuseTableEntry *>
(std::bsearch(&key, grimMusicTable,
sizeof(grimMusicTable) / sizeof(grimMusicTable[0]),
sizeof(grimMusicTable[0]), compareStates));
const imuseTableEntry *e = static_cast<imuseTableEntry *>(std::bsearch(&key, grimMusicTable,
sizeof(grimMusicTable) / sizeof(grimMusicTable[0]), sizeof(grimMusicTable[0]), compareStates));
if (e == NULL) {
warning("Unknown IMuse state %d\n", state);
return;
@ -359,15 +355,15 @@ void Mixer::setImuseSeq(int state) {
}
}
if (newSound != seqSound_) {
if (newSound != _seqSound) {
if (newSound != NULL)
newSound->reset();
seqSound_ = newSound;
_seqSound = newSound;
}
}
Sound *Mixer::findSfx(const char *filename) {
for (sound_list::iterator i = sfxSounds_.begin(); i != sfxSounds_.end(); i++) {
for (sound_list::iterator i = _sfxSounds.begin(); i != _sfxSounds.end(); i++) {
if (std::strcmp((*i)->filename(), filename) == 0)
return *i;
}
@ -375,33 +371,33 @@ Sound *Mixer::findSfx(const char *filename) {
}
bool Mixer::voicePlaying() const {
return ! voiceSounds_.empty();
return !_voiceSounds.empty();
}
void Mixer::getAudio(int16 *data, int numSamples) {
memset(data, 0, numSamples * 2);
for (sound_list::iterator i = voiceSounds_.begin(); i != voiceSounds_.end(); ) {
for (sound_list::iterator i = _voiceSounds.begin(); i != _voiceSounds.end(); ) {
(*i)->mix(data, numSamples);
if ((*i)->done())
i = voiceSounds_.erase(i);
i = _voiceSounds.erase(i);
else
i++;
}
for (sound_list::iterator i = sfxSounds_.begin(); i != sfxSounds_.end(); ) {
for (sound_list::iterator i = _sfxSounds.begin(); i != _sfxSounds.end(); ) {
(*i)->mix(data, numSamples);
if ((*i)->done())
i = sfxSounds_.erase(i);
i = _sfxSounds.erase(i);
else
i++;
}
if (seqSound_ != NULL) {
seqSound_->mix(data, numSamples);
if (seqSound_->done())
seqSound_ = NULL;
} else if (musicSound_ != NULL) {
musicSound_->mix(data, numSamples);
if (musicSound_->done())
musicSound_->reset();
if (_seqSound != NULL) {
_seqSound->mix(data, numSamples);
if (_seqSound->done())
_seqSound = NULL;
} else if (_musicSound != NULL) {
_musicSound->mix(data, numSamples);
if (_musicSound->done())
_musicSound->reset();
}
}
@ -448,25 +444,25 @@ Sound::Sound(const char *filename, const char *data, int /* len */) : Resource(f
}
if (strcasecmp(extension, "wav") == 0) {
numChannels_ = READ_LE_UINT16(headerPos + 22);
_numChannels = READ_LE_UINT16(headerPos + 22);
dataStart = headerPos + 28 + READ_LE_UINT32(headerPos + 16);
dataSize = READ_LE_UINT32(dataStart - 4);
} else if (strcasecmp(extension, "imc") == 0 || strcasecmp(extension, "imu") == 0) {
// Ignore MAP info for now...
if (memcmp(headerPos + 16, "FRMT", 4) != 0)
error("FRMT block not where it was expected\n");
numChannels_ = READ_BE_UINT32(headerPos + 40);
dataStart = headerPos + 24 + READ_BE_UINT32(headerPos + 12);
dataSize = READ_BE_UINT32(dataStart - 4);
} else {
// Ignore MAP info for now...
if (memcmp(headerPos + 16, "FRMT", 4) != 0)
error("FRMT block not where it was expected\n");
_numChannels = READ_BE_UINT32(headerPos + 40);
dataStart = headerPos + 24 + READ_BE_UINT32(headerPos + 12);
dataSize = READ_BE_UINT32(dataStart - 4);
} else {
error("Unrecognized extension for sound file %s\n", filename);
}
if (strcasecmp(extension, "wav") == 0 || strcasecmp(extension, "imc") == 0) {
// Uncompress the samples
numSamples_ = dataSize / 2;
samples_ = new int16[dataSize / 2];
int16 *destPos = samples_;
_numSamples = dataSize / 2;
_samples = new int16[dataSize / 2];
int16 *destPos = _samples;
const char *srcPos = dataStart;
for (int i = 1; i < numBlocks; i++) { // Skip header block
if (std::strcmp(codecsStart + 5 * *(uint8 *)(data + 6 + i * 9), "VIMA") != 0)
@ -477,36 +473,36 @@ Sound::Sound(const char *filename, const char *data, int /* len */) : Resource(f
destPos += READ_BE_UINT32(data + 7 + i * 9) / 2;
}
} else {
numSamples_ = dataSize / 2;
samples_ = new int16[dataSize / 2];
std::memcpy(samples_, dataStart, dataSize);
_numSamples = dataSize / 2;
_samples = new int16[dataSize / 2];
std::memcpy(_samples, dataStart, dataSize);
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
for (int i = 0; i < numSamples_; i++)
samples_[i] = SDL_Swap16(samples_[i]);
for (int i = 0; i < _numSamples; i++)
_samples[i] = SDL_Swap16(_samples[i]);
#endif
}
currPos_ = 0;
_currPos = 0;
}
void Sound::reset() {
currPos_ = 0;
_currPos = 0;
}
void Sound::mix(int16 *data, int samples) {
while (samples > 0 && currPos_ < numSamples_) {
clampedAdd(*data, samples_[currPos_]);
while (samples > 0 && _currPos < _numSamples) {
clampedAdd(*data, _samples[_currPos]);
data++;
if (numChannels_ == 1) {
*data += samples_[currPos_];
if (_numChannels == 1) {
*data += _samples[_currPos];
samples--;
data++;
}
currPos_++;
_currPos++;
samples--;
}
}
Sound::~Sound() {
delete[] samples_;
delete[] _samples;
}

16
sound.h
View File

@ -27,13 +27,13 @@ public:
Sound(const char *filename, const char *data, int len);
~Sound();
bool done() const { return currPos_ >= numSamples_; }
bool hasReachedPos(int position) const { return currPos_ >= position; }
int getCurrPos() const {return currPos_;}
bool done() const { return _currPos >= _numSamples; }
bool hasReachedPos(int position) const { return _currPos >= position; }
int getCurrPos() const {return _currPos;}
private:
int numSamples_, numChannels_, currPos_;
int16 *samples_;
int _numSamples, _numChannels, _currPos;
int16 *_samples;
static void init();
@ -65,10 +65,10 @@ private:
Mixer();
~Mixer();
static Mixer *instance_;
static Mixer *_instance;
typedef std::list<ResPtr<Sound> > sound_list;
sound_list voiceSounds_, sfxSounds_;
ResPtr<Sound> musicSound_, seqSound_;
sound_list _voiceSounds, _sfxSounds;
ResPtr<Sound> _musicSound, _seqSound;
friend void mixerCallback(void *userdata, uint8 *stream, int len);
};

View File

@ -23,23 +23,22 @@
#include "driver_gl.h"
TextObject::TextObject(const char *text, const int x, const int y, const Color& fgColor) :
fgColor_(fgColor), x_(x), y_(y) {
strcpy(textID_, text);
_fgColor(fgColor), _x(x), _y(y) {
strcpy(_textID, text);
Engine::instance()->registerTextObject(this);
}
void TextObject::setX(int x) {x_ = x;}
void TextObject::setY(int y) {y_ = y;}
void TextObject::setColor(Color *newcolor) {fgColor_ = newcolor;}
void TextObject::setX(int x) {_x = x; }
void TextObject::setY(int y) {_y = y; }
void TextObject::setColor(Color *newcolor) { _fgColor = newcolor; }
void TextObject::draw() {
const char *localString = Localizer::instance()->localize(textID_).c_str();
const char *localString = Localizer::instance()->localize(_textID).c_str();
// This is also used for things like debugging in addition
// to dialogue so there aren't always translations
if (strrchr(localString, '/') != NULL) {
g_driver->drawEmergString(x_, y_, strrchr(localString, '/') + 1, fgColor_);
g_driver->drawEmergString(_x, _y, strrchr(localString, '/') + 1, _fgColor);
} else {
g_driver->drawEmergString(x_, y_, localString, fgColor_);
g_driver->drawEmergString(_x, _y, localString, _fgColor);
}
}

View File

@ -31,12 +31,12 @@ public:
void setY(int y);
void setColor(Color *newColor);
const char *name() const { return textID_; }
const char *name() const { return _textID; }
void draw();
protected:
char textID_[10];
Color fgColor_;
int x_, y_;
char _textID[10];
Color _fgColor;
int _x, _y;
};
#endif

View File

@ -44,10 +44,10 @@ int residual_vsscanf(const char *str, int field_count, const char *format, va_li
}
TextSplitter::TextSplitter(const char *data, int len) {
data_ = new char[len + 1];
std::memcpy(data_, data, len);
data_[len] = '\0';
curr_line_ = data_;
_data = new char[len + 1];
std::memcpy(_data, data, len);
_data[len] = '\0';
_curr_line = _data;
processLine();
}
@ -83,35 +83,35 @@ void TextSplitter::scanString(const char *fmt, int field_count, ...) {
va_end(va);
nextLine();
}
}
void TextSplitter::processLine() {
if (eof())
return;
next_line_ = std::strchr(curr_line_, '\n');
if (next_line_ != NULL) {
*next_line_ = '\0';
next_line_++;
_next_line = std::strchr(_curr_line, '\n');
if (_next_line != NULL) {
*_next_line = '\0';
_next_line++;
}
// Cut off comments
char *comment_start = std::strchr(curr_line_, '#');
char *comment_start = std::strchr(_curr_line, '#');
if (comment_start != NULL)
*comment_start = '\0';
// Cut off trailing whitespace (including '\r')
char *strend = std::strchr(curr_line_, '\0');
while (strend > curr_line_ && std::isspace(strend[-1]))
char *strend = std::strchr(_curr_line, '\0');
while (strend > _curr_line && std::isspace(strend[-1]))
strend--;
*strend = '\0';
// Skip blank lines
if (*curr_line_ == '\0')
if (*_curr_line == '\0')
nextLine();
// Convert to lower case
if (! eof())
for (char *s = curr_line_; *s != '\0'; s++)
if (!eof())
for (char *s = _curr_line; *s != '\0'; s++)
*s = std::tolower(*s);
}

View File

@ -29,14 +29,14 @@ public:
TextSplitter(const char *data, int len);
char *nextLine() {
curr_line_ = next_line_;
_curr_line = _next_line;
processLine();
return curr_line_;
return _curr_line;
}
char *currentLine() { return curr_line_; }
const char *currentLine() const { return curr_line_; }
bool eof() const { return curr_line_ == NULL; }
char *currentLine() { return _curr_line; }
const char *currentLine() const { return _curr_line; }
bool eof() const { return _curr_line == NULL; }
// Check if the current line contains 'needle'
bool TextSplitter::checkString(const char *needle);
@ -54,10 +54,10 @@ public:
#endif
;
~TextSplitter() { delete[] data_; }
~TextSplitter() { delete[] _data; }
private:
char *data_, *curr_line_, *next_line_;
char *_data, *_curr_line, *_next_line;
void processLine();
};

View File

@ -22,20 +22,21 @@
class Vector3d {
public:
float coords_[3]; // Make sure this stays as an array so
// it can be passed to GL functions
float _coords[3]; // Make sure this stays as an array so
float& x() { return coords_[0]; }
float x() const { return coords_[0]; }
float& y() { return coords_[1]; }
float y() const { return coords_[1]; }
float& z() { return coords_[2]; }
float z() const { return coords_[2]; }
float& x() { return _coords[0]; }
float x() const { return _coords[0]; }
float& y() { return _coords[1]; }
float y() const { return _coords[1]; }
float& z() { return _coords[2]; }
float z() const { return _coords[2]; }
Vector3d() { this->x() = 0; this->y() = 0; this->z() = 0; }
Vector3d() {this->x() = 0; this->y() = 0; this->z() = 0;}
Vector3d(float x, float y, float z) {
this->x() = x; this->y() = y; this->z() = z;
}
Vector3d(const Vector3d &v) {
x() = v.x(); y() = v.y(); z() = v.z();
}

View File

@ -41,54 +41,52 @@ void Sector::load0(TextSplitter &ts, char *name, int id) {
float height = 12345.f; // Yaz: this is in the original code...
Vector3d tempVert;
name_ = name;
id_ = id;
_name = name;
_id = id;
ts.scanString(" type %256s", 1, buf);
// Flags used in function at 4A66C0 (buildWalkPlane)
if (strstr(buf, "walk"))
type_ = 0x1000;
_type = 0x1000;
else if (strstr(buf, "funnel"))
type_ = 0x1100;
_type = 0x1100;
else if (strstr(buf, "camera"))
type_ = 0x2000;
_type = 0x2000;
else if (strstr(buf, "special"))
type_ = 0x4000;
_type = 0x4000;
else if (strstr(buf, "chernobyl"))
type_ = 0x8000;
_type = 0x8000;
else
error("Unknown sector type '%s' in room setup", buf);
ts.scanString(" default visibility %256s", 1, buf);
if (strcmp(buf, "visible") == 0)
visible_ = true;
_visible = true;
else if (strcmp(buf, "invisible") == 0)
visible_ = false;
_visible = false;
else
error("Invalid visibility spec: %s\n", buf);
ts.scanString(" height %f", 1, &height_);
ts.scanString(" numvertices %d", 1, &numVertices_);
vertices_ = new Vector3d[numVertices_ + 1];
ts.scanString(" height %f", 1, &_height);
ts.scanString(" numvertices %d", 1, &_numVertices);
_vertices = new Vector3d[_numVertices + 1];
ts.scanString(" vertices: %f %f %f", 3, &vertices_[0].x(), &vertices_[0].y(),
&vertices_[0].z());
for (i=1;i<numVertices_;i++)
ts.scanString(" %f %f %f", 3, &vertices_[i].x(), &vertices_[i].y(), &vertices_[i].z());
ts.scanString(" vertices: %f %f %f", 3, &_vertices[0].x(), &_vertices[0].y(), &_vertices[0].z());
for (i = 1; i < _numVertices; i++)
ts.scanString(" %f %f %f", 3, &_vertices[i].x(), &_vertices[i].y(), &_vertices[i].z());
// Repeat the last vertex for convenience
vertices_[numVertices_] = vertices_[0];
_vertices[_numVertices] = _vertices[0];
normal_ = cross(vertices_[1] - vertices_[0],
vertices_[numVertices_ - 1] - vertices_[0]);
float length = normal_.magnitude();
_normal = cross(_vertices[1] - _vertices[0], _vertices[_numVertices - 1] - _vertices[0]);
float length = _normal.magnitude();
if (length > 0)
normal_ /= length;
_normal /= length;
}
void Sector::setVisible(bool visible) {
visible_ = visible;
_visible = visible;
}
bool Sector::isPointInSector(Vector3d point) const {
@ -101,9 +99,9 @@ bool Sector::isPointInSector(Vector3d point) const {
// (I don't know whether the box height actually has to be considered;
// if not then this will be fine as is.)
for (int i = 0; i < numVertices_; i++) {
Vector3d edge = vertices_[i+1] - vertices_[i];
Vector3d delta = point - vertices_[i];
for (int i = 0; i < _numVertices; i++) {
Vector3d edge = _vertices[i + 1] - _vertices[i];
Vector3d delta = point - _vertices[i];
if (edge.x() * delta.y() < edge.y() * delta.x())
return false;
}
@ -111,21 +109,21 @@ bool Sector::isPointInSector(Vector3d point) const {
}
Vector3d Sector::projectToPlane(Vector3d point) const {
if (normal_.z() == 0)
if (_normal.z() == 0)
error("Trying to walk along vertical plane\n");
// Formula: return p - (n . (p - v_0))/(n . k) k
Vector3d result = point;
result.z() -= dot(normal_, point - vertices_[0]) / normal_.z();
result.z() -= dot(_normal, point - _vertices[0]) / _normal.z();
return result;
}
Vector3d Sector::projectToPuckVector(Vector3d v) const {
if (normal_.z() == 0)
if (_normal.z() == 0)
error("Trying to walk along vertical plane\n");
Vector3d result = v;
result.z() -= dot(normal_, v) / normal_.z();
result.z() -= dot(_normal, v) / _normal.z();
return result;
}
@ -133,32 +131,32 @@ Vector3d Sector::projectToPuckVector(Vector3d v) const {
Vector3d Sector::closestPoint(Vector3d point) const {
// First try to project to the plane
Vector3d p2 = point;
p2 -= (dot(normal_, p2 - vertices_[0])) * normal_;
p2 -= (dot(_normal, p2 - _vertices[0])) * _normal;
if (isPointInSector(p2))
return p2;
// Now try to project to some edge
for (int i = 0; i < numVertices_; i++) {
Vector3d edge = vertices_[i + 1] - vertices_[i];
Vector3d delta = point - vertices_[i];
for (int i = 0; i < _numVertices; i++) {
Vector3d edge = _vertices[i + 1] - _vertices[i];
Vector3d delta = point - _vertices[i];
float scalar = dot(delta, edge) / dot(edge, edge);
if (scalar >= 0 && scalar <= 1 &&
delta.x() * edge.y() > delta.y() * edge.x())
// That last test is just whether the z-component
// of delta cross edge is positive; we don't
// want to return opposite edges.
return vertices_[i] + scalar * edge;
return _vertices[i] + scalar * edge;
}
// Otherwise, just find the closest vertex
float minDist = (point - vertices_[0]).magnitude();
float minDist = (point - _vertices[0]).magnitude();
int index = 0;
for (int i = 1; i < numVertices_; i++) {
float currDist = (point - vertices_[i]).magnitude();
for (int i = 1; i < _numVertices; i++) {
float currDist = (point - _vertices[i]).magnitude();
if (currDist < minDist) {
minDist = currDist;
index = i;
}
}
return vertices_[index];
return _vertices[index];
}

View File

@ -33,10 +33,10 @@ public:
void setVisible(bool visible);
const char *name() const { return name_.c_str(); }
const int id() const { return id_; }
const int type() const { return type_; } // FIXME: Implement type de-masking
bool visible() const { return visible_; }
const char *name() const { return _name.c_str(); }
const int id() const { return _id; }
const int type() const { return _type; } // FIXME: Implement type de-masking
bool visible() const { return _visible; }
bool isPointInSector(Vector3d point) const;
Vector3d projectToPlane(Vector3d point) const;
@ -45,14 +45,14 @@ public:
Vector3d closestPoint(Vector3d point) const;
private:
int numVertices_, id_;
int _numVertices, _id;
std::string name_;
int type_;
bool visible_;
Vector3d *vertices_;
float height_;
std::string _name;
int _type;
bool _visible;
Vector3d *_vertices;
float _height;
Vector3d normal_;
Vector3d _normal;
};
#endif