Initial commit
This commit is contained in:
291
engines/pegasus/energymonitor.cpp
Normal file
291
engines/pegasus/energymonitor.cpp
Normal file
@@ -0,0 +1,291 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* Additional copyright for this file:
|
||||
* Copyright (C) 1995-1997 Presto Studios, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/energymonitor.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/surface.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
Blinker::Blinker() {
|
||||
_sprite = nullptr;
|
||||
_frame1 = -1;
|
||||
_frame2 = -1;
|
||||
_blinkDuration = 0;
|
||||
}
|
||||
|
||||
void Blinker::startBlinking(Sprite *sprite, int32 frame1, int32 frame2, uint32 numBlinks, TimeValue blinkDuration, TimeScale blinkScale) {
|
||||
stopBlinking();
|
||||
_sprite = sprite;
|
||||
_frame1 = frame1;
|
||||
_frame2 = frame2;
|
||||
_blinkDuration = blinkDuration;
|
||||
setScale(blinkScale);
|
||||
setSegment(0, blinkDuration * numBlinks * 2, blinkScale);
|
||||
setTime(0);
|
||||
start();
|
||||
}
|
||||
|
||||
void Blinker::stopBlinking() {
|
||||
if (_sprite) {
|
||||
_sprite->setCurrentFrameIndex(_frame2);
|
||||
_sprite = nullptr;
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
void Blinker::timeChanged(const TimeValue time) {
|
||||
if (_sprite && _blinkDuration != 0) {
|
||||
if (((time / _blinkDuration) & 1) != 0 || time == getDuration()) {
|
||||
_sprite->setCurrentFrameIndex(_frame2);
|
||||
if (!isRunning())
|
||||
stopBlinking();
|
||||
} else {
|
||||
_sprite->setCurrentFrameIndex(_frame1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
kEnergyExpiredFlag = 1
|
||||
};
|
||||
|
||||
EnergyMonitor *g_energyMonitor = nullptr;
|
||||
|
||||
EnergyMonitor::EnergyMonitor() : IdlerAnimation(kEnergyBarID), _energyLight(kWarningLightID) {
|
||||
_stage = kStageNoStage;
|
||||
|
||||
_calibrating = false;
|
||||
_dontFlash = false;
|
||||
|
||||
setBounds(338, 48, 434, 54);
|
||||
|
||||
setDisplayOrder(kEnergyBarOrder);
|
||||
startDisplaying();
|
||||
|
||||
SpriteFrame *frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, kLightOffID);
|
||||
_energyLight.addFrame(frame, 0, 0);
|
||||
|
||||
frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, kLightYellowID);
|
||||
_energyLight.addFrame(frame, 0, 0);
|
||||
|
||||
frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, kLightOrangeID);
|
||||
_energyLight.addFrame(frame, 0, 0);
|
||||
|
||||
frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, kLightRedID);
|
||||
_energyLight.addFrame(frame, 0, 0);
|
||||
|
||||
_energyLight.setBounds(540, 35, 600, 59);
|
||||
_energyLight.setDisplayOrder(kEnergyLightOrder);
|
||||
_energyLight.startDisplaying();
|
||||
|
||||
setScale(1);
|
||||
setSegment(0, kMaxJMPEnergy);
|
||||
|
||||
setEnergyValue(kCasualEnergy);
|
||||
|
||||
g_energyMonitor = this;
|
||||
}
|
||||
|
||||
EnergyMonitor::~EnergyMonitor() {
|
||||
g_energyMonitor = nullptr;
|
||||
}
|
||||
|
||||
void EnergyMonitor::setEnergyValue(const uint32 value) {
|
||||
if (isRunning()) {
|
||||
stop();
|
||||
setTime(getStop() - value);
|
||||
start();
|
||||
} else {
|
||||
setTime(getStop() - value);
|
||||
}
|
||||
}
|
||||
|
||||
void EnergyMonitor::startEnergyDraining() {
|
||||
if (!isRunning()) {
|
||||
_energyLight.show();
|
||||
start();
|
||||
show();
|
||||
}
|
||||
}
|
||||
|
||||
void EnergyMonitor::setEnergyDrainRate(Common::Rational rate) {
|
||||
setRate(rate);
|
||||
}
|
||||
|
||||
Common::Rational EnergyMonitor::getEnergyDrainRate() {
|
||||
return getRate();
|
||||
}
|
||||
|
||||
void EnergyMonitor::stopEnergyDraining() {
|
||||
if (isRunning()) {
|
||||
stop();
|
||||
_energyLight.hide();
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
void EnergyMonitor::drainEnergy(const int32 delta) {
|
||||
setTime(getTime() + delta);
|
||||
}
|
||||
|
||||
int32 EnergyMonitor::getCurrentEnergy() {
|
||||
return kMaxJMPEnergy - getTime();
|
||||
}
|
||||
|
||||
void EnergyMonitor::timeChanged(const TimeValue currentTime) {
|
||||
if (currentTime == getStop()) {
|
||||
if (g_vm->getEnergyDeathReason() != -1)
|
||||
g_vm->die(g_vm->getEnergyDeathReason());
|
||||
} else {
|
||||
uint32 currentEnergy = kMaxJMPEnergy - currentTime;
|
||||
|
||||
EnergyStage newStage;
|
||||
if (currentEnergy > kWorriedEnergy)
|
||||
newStage = kStageCasual;
|
||||
else if (currentEnergy > kNervousEnergy)
|
||||
newStage = kStageWorried;
|
||||
else if (currentEnergy > kPanicStrickenEnergy)
|
||||
newStage = kStageNervous;
|
||||
else
|
||||
newStage = kStagePanicStricken;
|
||||
|
||||
if (_stage != newStage) {
|
||||
uint32 newFrame;
|
||||
|
||||
switch (newStage) {
|
||||
case kStageCasual:
|
||||
_barColor = g_system->getScreenFormat().RGBToColor(0x48, 0xB0, 0xD8);
|
||||
newFrame = kFrameLightOff;
|
||||
break;
|
||||
case kStageWorried:
|
||||
_barColor = g_system->getScreenFormat().RGBToColor(0xD8, 0xC0, 0x30);
|
||||
newFrame = kFrameLightYellow;
|
||||
break;
|
||||
case kStageNervous:
|
||||
_barColor = g_system->getScreenFormat().RGBToColor(0xD8, 0x78, 0x38);
|
||||
newFrame = kFrameLightOrange;
|
||||
break;
|
||||
case kStagePanicStricken:
|
||||
_barColor = g_system->getScreenFormat().RGBToColor(0xD8, 0x40, 0x38);
|
||||
newFrame = kFrameLightRed;
|
||||
break;
|
||||
default:
|
||||
error("no stage in energy monitor?");
|
||||
break;
|
||||
}
|
||||
|
||||
_stage = newStage;
|
||||
uint32 oldFrame = _energyLight.getCurrentFrameIndex();
|
||||
|
||||
if (!_calibrating) {
|
||||
if (oldFrame > newFrame || oldFrame == 0xffffffff || _dontFlash) {
|
||||
_energyLight.setCurrentFrameIndex(newFrame);
|
||||
_dontFlash = false;
|
||||
} else {
|
||||
_lightBlinker.startBlinking(&_energyLight, oldFrame, newFrame, 4, 1, 3);
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Common::Rect r;
|
||||
calcLevelRect(r);
|
||||
if (r != _levelRect) {
|
||||
_levelRect = r;
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnergyMonitor::calcLevelRect(Common::Rect &r) {
|
||||
if (getStop() == 0) {
|
||||
r = Common::Rect();
|
||||
} else {
|
||||
getBounds(r);
|
||||
r.left = r.right - r.width() * (kMaxJMPEnergy - getTime()) / getStop();
|
||||
}
|
||||
}
|
||||
|
||||
void EnergyMonitor::draw(const Common::Rect &r) {
|
||||
Common::Rect r2 = r.findIntersectingRect(_levelRect);
|
||||
|
||||
if (!r2.isEmpty()) {
|
||||
Graphics::Surface *screen = g_vm->_gfx->getWorkArea();
|
||||
screen->fillRect(r2, _barColor);
|
||||
}
|
||||
}
|
||||
|
||||
void EnergyMonitor::calibrateEnergyBar() {
|
||||
_calibrating = true;
|
||||
|
||||
g_vm->setEnergyDeathReason(-1);
|
||||
|
||||
uint32 numFrames = _energyLight.getNumFrames();
|
||||
for (uint32 i = 1; i < numFrames; i++) {
|
||||
_energyLight.setCurrentFrameIndex(i);
|
||||
_energyLight.show();
|
||||
g_vm->delayShell(1, 3);
|
||||
_energyLight.hide();
|
||||
g_vm->delayShell(1, 3);
|
||||
}
|
||||
|
||||
_energyLight.setCurrentFrameIndex(0);
|
||||
_energyLight.hide();
|
||||
|
||||
setEnergyValue(0);
|
||||
setEnergyDrainRate(-(int32)kMaxJMPEnergy / 2);
|
||||
show();
|
||||
|
||||
// Make sure warning light is hidden...
|
||||
_energyLight.hide();
|
||||
while (getCurrentEnergy() != (int32)kMaxJMPEnergy) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
g_vm->refreshDisplay();
|
||||
setEnergyDrainRate(0);
|
||||
hide();
|
||||
|
||||
_calibrating = false;
|
||||
}
|
||||
|
||||
void EnergyMonitor::restoreLastEnergyValue() {
|
||||
_dontFlash = true;
|
||||
setEnergyValue(g_vm->getSavedEnergyValue());
|
||||
g_vm->resetEnergyDeathReason();
|
||||
}
|
||||
|
||||
void EnergyMonitor::saveCurrentEnergyValue() {
|
||||
g_vm->setLastEnergyValue(getCurrentEnergy());
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
Reference in New Issue
Block a user