mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 14:18:37 +00:00
300 lines
7.2 KiB
C++
300 lines
7.2 KiB
C++
/* 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 2
|
|
* 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, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#include "pegasus/energymonitor.h"
|
|
#include "pegasus/pegasus.h"
|
|
#include "pegasus/surface.h"
|
|
|
|
namespace Pegasus {
|
|
|
|
Blinker::Blinker() {
|
|
_sprite = 0;
|
|
_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 = 0;
|
|
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 = 0;
|
|
|
|
EnergyMonitor::EnergyMonitor() : IdlerAnimation(kEnergyBarID), _energyLight(kWarningLightID) {
|
|
PegasusEngine *vm = (PegasusEngine *)g_engine;
|
|
|
|
_stage = kStageNoStage;
|
|
|
|
_calibrating = false;
|
|
_dontFlash = false;
|
|
|
|
setBounds(338, 48, 434, 54);
|
|
|
|
setDisplayOrder(kEnergyBarOrder);
|
|
startDisplaying();
|
|
|
|
SpriteFrame *frame = new SpriteFrame();
|
|
frame->initFromPICTResource(vm->_resFork, kLightOffID);
|
|
_energyLight.addFrame(frame, 0, 0);
|
|
|
|
frame = new SpriteFrame();
|
|
frame->initFromPICTResource(vm->_resFork, kLightYellowID);
|
|
_energyLight.addFrame(frame, 0, 0);
|
|
|
|
frame = new SpriteFrame();
|
|
frame->initFromPICTResource(vm->_resFork, kLightOrangeID);
|
|
_energyLight.addFrame(frame, 0, 0);
|
|
|
|
frame = new SpriteFrame();
|
|
frame->initFromPICTResource(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 = 0;
|
|
}
|
|
|
|
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()) {
|
|
PegasusEngine *vm = (PegasusEngine *)g_engine;
|
|
if (vm->getEnergyDeathReason() != -1)
|
|
vm->die(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 = ((PegasusEngine *)g_engine)->_gfx->getWorkArea();
|
|
screen->fillRect(r2, _barColor);
|
|
}
|
|
}
|
|
|
|
void EnergyMonitor::calibrateEnergyBar() {
|
|
PegasusEngine *vm = (PegasusEngine *)g_engine;
|
|
|
|
_calibrating = true;
|
|
|
|
vm->setEnergyDeathReason(-1);
|
|
|
|
uint32 numFrames = _energyLight.getNumFrames();
|
|
for (uint32 i = 1; i < numFrames; i++) {
|
|
_energyLight.setCurrentFrameIndex(i);
|
|
_energyLight.show();
|
|
vm->delayShell(1, 3);
|
|
_energyLight.hide();
|
|
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();
|
|
vm->checkCallBacks();
|
|
vm->refreshDisplay();
|
|
g_system->delayMillis(10);
|
|
}
|
|
|
|
vm->refreshDisplay();
|
|
setEnergyDrainRate(0);
|
|
hide();
|
|
|
|
_calibrating = false;
|
|
}
|
|
|
|
void EnergyMonitor::restoreLastEnergyValue() {
|
|
PegasusEngine *vm = (PegasusEngine *)g_engine;
|
|
|
|
_dontFlash = true;
|
|
setEnergyValue(vm->getSavedEnergyValue());
|
|
vm->resetEnergyDeathReason();
|
|
}
|
|
|
|
void EnergyMonitor::saveCurrentEnergyValue() {
|
|
((PegasusEngine *)g_engine)->setLastEnergyValue(getCurrentEnergy());
|
|
}
|
|
|
|
} // End of namespace Pegasus
|