mirror of
https://github.com/libretro/scummvm.git
synced 2024-11-30 21:00:39 +00:00
format "_" in names,
format code a bit
This commit is contained in:
parent
06935dace4
commit
39a4b54d30
396
actor.cpp
396
actor.cpp
@ -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
122
actor.h
@ -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;
|
||||
};
|
||||
|
63
bitmap.cpp
63
bitmap.cpp
@ -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--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
30
bitmap.h
30
bitmap.h
@ -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
26
color.h
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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
|
||||
|
511
costume.cpp
511
costume.cpp
@ -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);
|
||||
}
|
||||
|
72
costume.h
72
costume.h
@ -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
|
||||
|
@ -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++) {
|
||||
|
328
driver_gl.cpp
328
driver_gl.cpp
@ -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);
|
||||
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
void drawSmushFrame(int offsetX, int offsetY);
|
||||
|
||||
private:
|
||||
GLuint emergFont;
|
||||
GLuint _emergFont;
|
||||
int _smushNumTex;
|
||||
GLuint *_smushTexIds;
|
||||
int _smushWidth;
|
||||
|
67
engine.cpp
67
engine.cpp
@ -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;
|
||||
}
|
||||
|
58
engine.h
58
engine.h
@ -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
|
||||
|
190
keyframe.cpp
190
keyframe.cpp
@ -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
|
||||
|
33
keyframe.h
33
keyframe.h
@ -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
42
lab.cpp
@ -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
24
lab.h
@ -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;
|
||||
};
|
||||
|
54
lipsynch.cpp
54
lipsynch.cpp
@ -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]);
|
||||
|
14
lipsynch.h
14
lipsynch.h
@ -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
|
||||
|
18
localize.cpp
18
localize.cpp
@ -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;
|
||||
|
@ -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
122
lua.cpp
@ -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;
|
||||
}
|
||||
|
14
main.cpp
14
main.cpp
@ -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);
|
||||
}
|
||||
|
14
material.cpp
14
material.cpp
@ -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);
|
||||
}
|
||||
|
12
material.h
12
material.h
@ -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
|
||||
|
54
matrix3.cpp
54
matrix3.cpp
@ -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);
|
||||
}
|
||||
|
50
matrix3.h
50
matrix3.h
@ -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;
|
||||
}
|
||||
|
12
matrix4.cpp
12
matrix4.cpp
@ -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;
|
||||
}
|
||||
|
||||
|
18
matrix4.h
18
matrix4.h
@ -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
424
model.cpp
@ -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
86
model.h
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
26
registry.cpp
26
registry.cpp
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
59
resource.cpp
59
resource.cpp
@ -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);
|
||||
}
|
||||
|
72
resource.h
72
resource.h
@ -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
133
scene.cpp
@ -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
60
scene.h
@ -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 §ors_[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
|
||||
|
86
screen.cpp
86
screen.cpp
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
6
screen.h
6
screen.h
@ -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
118
sound.cpp
@ -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
16
sound.h
@ -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);
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
14
textsplit.h
14
textsplit.h
@ -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();
|
||||
};
|
||||
|
19
vector3d.h
19
vector3d.h
@ -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();
|
||||
}
|
||||
|
@ -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];
|
||||
}
|
||||
|
22
walkplane.h
22
walkplane.h
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user