mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
1180 lines
37 KiB
C++
1180 lines
37 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.
|
|
*
|
|
* 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 "hypno/grammar.h"
|
|
#include "hypno/hypno.h"
|
|
|
|
#include "common/events.h"
|
|
#include "gui/message.h"
|
|
#include "graphics/cursorman.h"
|
|
|
|
namespace Hypno {
|
|
|
|
void WetEngine::initSegment(ArcadeShooting *arc) {
|
|
if (_arcadeMode == "Y1") {
|
|
_segmentShootSequenceOffset = 0;
|
|
_segmentShootSequenceMax = 3;
|
|
} else if (_arcadeMode == "Y3") {
|
|
_segmentShootSequenceOffset = 0;
|
|
_segmentShootSequenceMax = 7;
|
|
} else if (_arcadeMode == "Y4") {
|
|
_c40SegmentNext.clear();
|
|
|
|
_c40SegmentNext.push_back(2); // Road fork (down)
|
|
_c40SegmentPath.push_back(3); // Go straight
|
|
|
|
_c40SegmentNext.push_back(9); // Tunnel entry
|
|
_c40SegmentPath.push_back(9); // Go straight
|
|
_c40SegmentNext.push_back(1); // Tunnel section
|
|
_c40SegmentPath.push_back(11); // Tunnel exit
|
|
|
|
_c40SegmentNext.push_back(2); // Road fork
|
|
_c40SegmentPath.push_back(5); // Turn left
|
|
|
|
_c40SegmentNext.push_back(6); // Ramp
|
|
_c40SegmentPath.push_back(8); // Take ramp
|
|
|
|
_c40SegmentNext.push_back(15); // Road fork (up)
|
|
_c40SegmentPath.push_back(18); // Take right
|
|
|
|
_c40SegmentNext.push_back(22); // Tunnel entry
|
|
_c40SegmentPath.push_back(22); // Go straight
|
|
_c40SegmentNext.push_back(14); // Tunnel section
|
|
_c40SegmentPath.push_back(24); // Tunnel exit
|
|
|
|
_c40SegmentNext.push_back(15); // Road fork (up)
|
|
_c40SegmentPath.push_back(17); // Take left
|
|
|
|
_c40SegmentNext.push_back(19); // Ramp
|
|
_c40SegmentPath.push_back(21); // Take ramp
|
|
|
|
_c40SegmentNext.push_back(2); // Road fork (down)
|
|
_c40SegmentPath.push_back(3); // Go straight
|
|
|
|
_c40SegmentNext.push_back(26);
|
|
_c40SegmentIdx = 0;
|
|
_c40lastTurn = -1;
|
|
|
|
_segmentShootSequenceOffset = 0;
|
|
_segmentShootSequenceMax = 5;
|
|
} else if (_arcadeMode == "Y5") {
|
|
_c50LeftTurns = 0;
|
|
_c50RigthTurns = 0;
|
|
|
|
_segmentShootSequenceOffset = 1;
|
|
_segmentShootSequenceMax = 9;
|
|
} else {
|
|
_segmentShootSequenceOffset = 0;
|
|
_segmentShootSequenceMax = 0;
|
|
}
|
|
|
|
uint32 randomSegmentShootSequence = _segmentShootSequenceOffset + _rnd->getRandomNumber(_segmentShootSequenceMax);
|
|
debugC(1, kHypnoDebugArcade, "Select random sequence %d", randomSegmentShootSequence);
|
|
SegmentShoots segmentShoots = arc->shootSequence[randomSegmentShootSequence];
|
|
_segments = arc->segments;
|
|
_shootSequence = segmentShoots.shootSequence;
|
|
_segmentRepetitionMax = segmentShoots.segmentRepetition; // Usually zero
|
|
_segmentRepetition = 0;
|
|
_segmentOffset = 0;
|
|
_segmentIdx = _segmentOffset;
|
|
|
|
if (_arcadeMode == "Y3") {
|
|
ShootInfo si;
|
|
si.name = "SP_CBREAKER_L";
|
|
si.timestamp = 30 * (_segmentRepetitionMax + 1) - 3;
|
|
_shootSequence.push_back(si);
|
|
}
|
|
}
|
|
|
|
void WetEngine::findNextSegment(ArcadeShooting *arc) {
|
|
debugC(1, kHypnoDebugArcade, "Repetition %d of %d", _segmentRepetition, _segmentRepetitionMax);
|
|
Common::Point mousePos = g_system->getEventManager()->getMousePos();
|
|
|
|
if (_segmentRepetition < _segmentRepetitionMax) {
|
|
_segmentRepetition = _segmentRepetition + 1;
|
|
} else {
|
|
_segmentRepetition = 0;
|
|
_segmentRepetitionMax = 0;
|
|
if (_segments[_segmentIdx].type == 0xb3) {
|
|
if (_arcadeMode == "Y1") {
|
|
if (_rnd->getRandomBit())
|
|
_segmentIdx = _segmentIdx + 1;
|
|
else
|
|
_segmentIdx = _segmentIdx + 5;
|
|
} else if (_arcadeMode == "Y4") {
|
|
_segmentIdx = _c40SegmentNext[_c40SegmentIdx];
|
|
} else if (_arcadeMode == "Y5") {
|
|
int r = _rnd->getRandomNumber(4);
|
|
if (r == 0)
|
|
_segmentIdx = 1;
|
|
else
|
|
_segmentIdx = r + 4;
|
|
|
|
if (_segments[_segmentIdx].type == 'L') {
|
|
_shootSequence = arc->shootSequence[11].shootSequence;
|
|
_segmentRepetitionMax = 0;
|
|
} else if (_segments[_segmentIdx].type == 'R') {
|
|
_shootSequence = arc->shootSequence[12].shootSequence;
|
|
_segmentRepetitionMax = 0;
|
|
} else if (_segments[_segmentIdx].type == 'A') {
|
|
_shootSequence = arc->shootSequence[15].shootSequence;
|
|
_segmentRepetitionMax = 0;
|
|
} else if (_segments[_segmentIdx].type == 'P') {
|
|
r = _rnd->getRandomNumber(1);
|
|
_shootSequence = arc->shootSequence[13 + r].shootSequence; //13-14
|
|
_segmentRepetitionMax = 0;
|
|
}
|
|
} else
|
|
_segmentIdx = _segmentIdx + 1;
|
|
|
|
} else if (_segments[_segmentIdx].type == 0xc5) {
|
|
if (_arcadeMode == "Y1") {
|
|
if (mousePos.x <= 106)
|
|
_segmentIdx = _segmentIdx + 1;
|
|
else if (mousePos.x >= 213)
|
|
_segmentIdx = _segmentIdx + 3;
|
|
else
|
|
_segmentIdx = _segmentIdx + 2;
|
|
} else if (_arcadeMode == "Y4") {
|
|
if (mousePos.x <= 106)
|
|
_segmentIdx = _segmentIdx + 2;
|
|
else if (mousePos.x >= 213)
|
|
_segmentIdx = _segmentIdx + 3;
|
|
else
|
|
_segmentIdx = _segmentIdx + 1;
|
|
|
|
} else if (_arcadeMode == "Y5") {
|
|
if (mousePos.x <= 106) {
|
|
_segmentIdx = _segmentIdx + 2;
|
|
_c50LeftTurns++;
|
|
} else if (mousePos.x >= 213) {
|
|
_segmentIdx = _segmentIdx + 3;
|
|
_c50RigthTurns++;
|
|
} else
|
|
_segmentIdx = _segmentIdx + 1;
|
|
} else
|
|
error("Invalid segment type for mode: %s at the end of segment %x", _arcadeMode.c_str(), _segments[_segmentIdx].type);
|
|
|
|
} else if (_segments[_segmentIdx].type == 0xc2) {
|
|
if (mousePos.x <= 160)
|
|
_segmentIdx = _segmentIdx + 1;
|
|
else
|
|
_segmentIdx = _segmentIdx + 2;
|
|
} else if (_segments[_segmentIdx].type == 0xcc) {
|
|
if (mousePos.x <= 160)
|
|
_segmentIdx = _segmentIdx + 1;
|
|
else {
|
|
_segmentIdx = _segmentIdx + 2;
|
|
if (_arcadeMode == "Y3") {
|
|
ShootInfo si;
|
|
si.name = "SP_WALKER_U";
|
|
si.timestamp = 25;
|
|
_shootSequence.push_back(si);
|
|
}
|
|
}
|
|
} else if (_segments[_segmentIdx].type == 'Y') {
|
|
if (mousePos.x <= 160) {
|
|
_segmentIdx = _segmentIdx + 2;
|
|
if (_arcadeMode == "Y3") {
|
|
ShootInfo si;
|
|
si.name = "SP_WALKER_D";
|
|
si.timestamp = 25;
|
|
_shootSequence.push_back(si);
|
|
}
|
|
} else
|
|
_segmentIdx = _segmentIdx + 1;
|
|
|
|
/*} else if (_segments[_segmentIdx].type == 'a') {
|
|
_segmentIdx = 1;*/
|
|
} else if (_segments[_segmentIdx].type == 's') {
|
|
_segmentIdx = _segmentIdx + 10; // _segmentIdx = 11;
|
|
} else {
|
|
|
|
// Objective checking
|
|
if (availableObjectives() && checkArcadeObjectives()) {
|
|
if (_objIdx == 0) {
|
|
_objIdx = 1;
|
|
if (_arcadeMode == "Y1") {
|
|
_segmentOffset = 8;
|
|
_segmentRepetition = 0;
|
|
_segmentShootSequenceOffset = 8;
|
|
|
|
MVideo video(arc->hitBoss1Video, Common::Point(0, 0), false, true, false);
|
|
disableCursor();
|
|
runIntro(video);
|
|
} else if (_arcadeMode == "Y3")
|
|
_skipLevel = true;
|
|
} else {
|
|
_loseLevel = true;
|
|
return;
|
|
}
|
|
}
|
|
if (_segments[_segmentIdx].type == 0xc9) {
|
|
if (_arcadeMode == "Y3") {
|
|
_segmentOffset = _segmentIdx + 1;
|
|
_segmentShootSequenceOffset = 8;
|
|
_segmentShootSequenceMax = 7;
|
|
} else if (_arcadeMode == "Y4") {
|
|
if (_segmentOffset == 0) {
|
|
_segmentOffset = 13;
|
|
_segmentShootSequenceOffset = 10; // TODO
|
|
_segmentShootSequenceMax = 5; // TODO
|
|
} else {
|
|
_segmentOffset = 0;
|
|
_segmentShootSequenceOffset = 0;
|
|
_segmentShootSequenceMax = 5;
|
|
}
|
|
} else
|
|
error("Invalid segment type for mode: %s at the end of segment %x", _arcadeMode.c_str(), _segments[_segmentIdx].type);
|
|
} else if (_segments[_segmentIdx].type == 0xbb) {
|
|
_segmentOffset = 0;
|
|
_segmentShootSequenceOffset = 0;
|
|
_segmentShootSequenceMax = 7;
|
|
} else if (_segments[_segmentIdx].type == 0x61) {
|
|
_segmentOffset = _segmentOffset + 1; // _segmentOffset = 1;
|
|
_segmentShootSequenceOffset = 6;
|
|
_segmentShootSequenceMax = 4;
|
|
} else if (_segments[_segmentIdx].type == 0x63) {
|
|
_segmentOffset = _segmentOffset - 1; // _segmentOffset = 0;
|
|
//_segmentShootSequenceOffset = 0; // TODO
|
|
//_segmentShootSequenceMax = 7; // TODO
|
|
}
|
|
// TODO: refactor the following code to avoid using a variable here
|
|
bool addBarrier = false;
|
|
if (_arcadeMode == "Y4") {
|
|
if (_c40SegmentPath[_c40SegmentIdx] == _segmentIdx) {
|
|
_c40SegmentIdx++;
|
|
} else {
|
|
if (_c40lastTurn == int(_segmentIdx))
|
|
_health = 0;
|
|
else {
|
|
addBarrier = true;
|
|
_c40lastTurn = int(_segmentIdx);
|
|
}
|
|
}
|
|
} else if (_arcadeMode == "Y5") {
|
|
if (_c50LeftTurns >= 1 && _c50RigthTurns >= 3) {
|
|
_segmentIdx = 9; // last segment
|
|
return;
|
|
}
|
|
}
|
|
|
|
_segmentIdx = _segmentOffset;
|
|
// select a new shoot sequence
|
|
uint32 randomSegmentShootSequence = _segmentShootSequenceOffset + _rnd->getRandomNumber(_segmentShootSequenceMax);
|
|
debugC(1, kHypnoDebugArcade, "Selected random sequence %d", randomSegmentShootSequence);
|
|
SegmentShoots segmentShoots = arc->shootSequence[randomSegmentShootSequence];
|
|
_shootSequence = segmentShoots.shootSequence;
|
|
_segmentRepetitionMax = segmentShoots.segmentRepetition; // Usually one
|
|
|
|
if (_arcadeMode == "Y3") {
|
|
ShootInfo si;
|
|
if (_segmentOffset == 0)
|
|
si.name = "SP_CBREAKER_L";
|
|
else
|
|
si.name = "SP_CBREAKER_U";
|
|
|
|
si.timestamp = 30 * (_segmentRepetitionMax + 1) - 3;
|
|
_shootSequence.push_back(si);
|
|
} else if (_arcadeMode == "Y4" && addBarrier) {
|
|
// Add a barrier near the end
|
|
ShootInfo si;
|
|
si.name = "SP_BLOCKADE";
|
|
si.timestamp = (30 * _segmentRepetitionMax) - 20;
|
|
_shootSequence.push_back(si);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool WetEngine::checkTransition(ArcadeTransitions &transitions, ArcadeShooting *arc) {
|
|
ArcadeTransition at = *transitions.begin();
|
|
int ttime = at.time;
|
|
if (ttime == 0) { // This special case is only reachable in c33
|
|
assert(_objIdx == 1);
|
|
transitions.pop_front();
|
|
} else if (_background->decoder->getCurFrame() > ttime) {
|
|
|
|
if (at.video == "NONE") {
|
|
//TODO
|
|
return true;
|
|
}
|
|
|
|
if (_playerFrameSeps.size() == 1) {
|
|
_playerFrameStart = _playerFrameEnd + 1;
|
|
_playerFrameSep = *_playerFrameSeps.begin();
|
|
_playerFrameSeps.pop_front();
|
|
_playerFrameEnd = _playerFrames.size();
|
|
_playerFrameIdx = _playerFrameStart;
|
|
debugC(1, kHypnoDebugArcade, "New separator frames %d %d %d", _playerFrameStart, _playerFrameSep, _playerFrameEnd);
|
|
} else if (_playerFrameSeps.size() >= 2) {
|
|
_playerFrameStart = _playerFrameEnd + 1;
|
|
_playerFrameSep = *_playerFrameSeps.begin();
|
|
_playerFrameSeps.pop_front();
|
|
_playerFrameEnd = *_playerFrameSeps.begin();
|
|
_playerFrameSeps.pop_front();
|
|
_playerFrameIdx = _playerFrameStart;
|
|
debugC(1, kHypnoDebugArcade, "New separator frames %d %d %d", _playerFrameStart, _playerFrameSep, _playerFrameEnd);
|
|
}
|
|
|
|
if (_levelId == 33) {
|
|
if (checkArcadeObjectives()) {
|
|
_objIdx = 1;
|
|
} else {
|
|
// We do not play the transition, just skip the level
|
|
_loseLevel = true;
|
|
return true;
|
|
}
|
|
} else if (_levelId == 52) {
|
|
// Ignore the first objective, this will be checked when the targets are missed
|
|
// just go to the second one
|
|
_objIdx = 1;
|
|
} else if (_levelId == 61 && transitions.size() == 1) {
|
|
// Check the first objective during the second transition
|
|
if (checkArcadeObjectives()) {
|
|
_objIdx = 1;
|
|
} else {
|
|
// We do not play the transition, just skip the level
|
|
_loseLevel = true;
|
|
return true;
|
|
}
|
|
}
|
|
if (at.video.empty() && !at.palette.empty()) {
|
|
_background->decoder->pauseVideo(true);
|
|
_currentPalette = at.palette;
|
|
loadPalette(_currentPalette);
|
|
_background->decoder->pauseVideo(false);
|
|
drawPlayer();
|
|
updateScreen(*_background);
|
|
drawScreen();
|
|
} else if (!at.video.empty()) {
|
|
_background->decoder->pauseVideo(true);
|
|
debugC(1, kHypnoDebugArcade, "Playing transition %s", at.video.c_str());
|
|
MVideo video(at.video, Common::Point(0, 0), false, true, false);
|
|
disableCursor();
|
|
runIntro(video);
|
|
|
|
if (!at.palette.empty())
|
|
_currentPalette = at.palette;
|
|
|
|
loadPalette(_currentPalette);
|
|
_background->decoder->pauseVideo(false);
|
|
drawPlayer();
|
|
updateScreen(*_background);
|
|
drawScreen();
|
|
drawCursorArcade(g_system->getEventManager()->getMousePos());
|
|
if (!_music.empty())
|
|
playSound(_music, 0, _musicRate); // restore music
|
|
} else
|
|
error ("Invalid transition at %d", ttime);
|
|
|
|
transitions.pop_front();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
void WetEngine::runAfterArcade(ArcadeShooting *arc) {
|
|
_checkpoint = _currentLevel;
|
|
|
|
_playerFrameSeps.clear();
|
|
for (Frames::iterator it =_playerFrames.begin(); it != _playerFrames.end(); ++it) {
|
|
(*it)->free();
|
|
delete (*it);
|
|
}
|
|
_playerFrames.clear();
|
|
|
|
if (_health < 0)
|
|
_health = 0;
|
|
|
|
if (arc->mode == "YT") {
|
|
for (Frames::iterator it = _c33PlayerCursor.begin(); it != _c33PlayerCursor.end(); ++it) {
|
|
(*it)->free();
|
|
delete (*it);
|
|
}
|
|
}
|
|
|
|
if (isDemo() && _variant != "Demo" && _variant != "M&MCD" && _restoredContentEnabled) {
|
|
showDemoScore();
|
|
} else if (!isDemo() || _variant == "Demo" || _variant == "M&MCD" || _variant == "Gen4") {
|
|
byte *palette;
|
|
Graphics::Surface *frame = decodeFrame("c_misc/zones.smk", 12, &palette);
|
|
loadPalette(palette, 0, 256);
|
|
free(palette);
|
|
uint32 c = kHypnoColorGreen; // green
|
|
int bonusCounter = 0;
|
|
int scoreCounter = _score - _bonus;
|
|
bool extraLife = false;
|
|
assert(scoreCounter >= 0);
|
|
bool skip = false;
|
|
Common::Event event;
|
|
while (!shouldQuit() && !skip) {
|
|
|
|
drawImage(*frame, 0, 0, false);
|
|
drawString("scifi08.fgx", Common::String::format("Lives : %d", _lives), 36, 2, 0, c);
|
|
drawString("scifi08.fgx", Common::String::format("%-20s = %7d", "SHOTS FIRED", _stats.shootsFired), 60, 46, 0, c);
|
|
drawString("scifi08.fgx", Common::String::format("%-20s = %7d", "ENEMY TARGETS", _stats.enemyTargets), 60, 56, 0, c);
|
|
drawString("scifi08.fgx", Common::String::format("%-20s = %7d", "TARGETS DESTROYED", _stats.targetsDestroyed), 60, 66, 0, c);
|
|
drawString("scifi08.fgx", Common::String::format("%-20s = %7d", "TARGETS MISSED", _stats.targetsMissed), 60, 76, 0, c);
|
|
drawString("scifi08.fgx", Common::String::format("%-20s = %5d %%", "KILL RATIO", killRatio()), 60, 86, 0, c);
|
|
drawString("scifi08.fgx", Common::String::format("%-20s = %5d %%", "ACCURACY", accuracyRatio()), 60, 96, 0, c);
|
|
drawString("scifi08.fgx", Common::String::format("%-20s = %5d %%", "ENERGY", _health), 60, 106, 0, c);
|
|
|
|
while (g_system->getEventManager()->pollEvent(event)) {
|
|
// Events
|
|
switch (event.type) {
|
|
|
|
case Common::EVENT_QUIT:
|
|
case Common::EVENT_RETURN_TO_LAUNCHER:
|
|
break;
|
|
|
|
case Common::EVENT_LBUTTONDOWN:
|
|
case Common::EVENT_KEYDOWN:
|
|
bonusCounter = _bonus;
|
|
drawString("scifi08.fgx", Common::String::format("%-20s = %3d pts", "BONUS", _bonus), 60, 116, 0, c);
|
|
drawString("scifi08.fgx", Common::String::format("%-20s = %3d pts", "SCORE", _score), 60, 126, 0, c);
|
|
skip = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bonusCounter < _bonus) {
|
|
bonusCounter++;
|
|
scoreCounter++;
|
|
drawString("scifi08.fgx", Common::String::format("%-20s = %3d pts", "BONUS", bonusCounter), 60, 116, 0, c);
|
|
drawString("scifi08.fgx", Common::String::format("%-20s = %3d pts", "SCORE", scoreCounter), 60, 126, 0, c);
|
|
}
|
|
|
|
extraLife |= checkScoreMilestones(scoreCounter); // This increase the number of lives, if necessary
|
|
if (extraLife) {
|
|
drawString("scifi08.fgx", "EXTRA LIFE", 164, 140, 0, kHypnoColorRed);
|
|
}
|
|
|
|
drawScreen();
|
|
g_system->delayMillis(25);
|
|
}
|
|
frame->free();
|
|
delete frame;
|
|
}
|
|
|
|
if (!arc->postStatsVideo.empty()) {
|
|
MVideo video(arc->postStatsVideo, Common::Point(0, 0), false, true, false);
|
|
disableCursor();
|
|
runIntro(video);
|
|
}
|
|
}
|
|
void WetEngine::restoreScoreMilestones(int score) {
|
|
if (score == 0) {
|
|
_scoreMilestones.clear();
|
|
_scoreMilestones.push_back(10000);
|
|
_scoreMilestones.push_back(25000);
|
|
_scoreMilestones.push_back(50000);
|
|
_scoreMilestones.push_back(100000);
|
|
} else {
|
|
while (true) {
|
|
if (_scoreMilestones.empty() || score < *_scoreMilestones.begin())
|
|
break;
|
|
_scoreMilestones.pop_front();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool WetEngine::checkScoreMilestones(int score) {
|
|
bool extraLife = false;
|
|
while (true) {
|
|
if (_scoreMilestones.empty() || score < *_scoreMilestones.begin())
|
|
break;
|
|
_scoreMilestones.pop_front();
|
|
_lives = _lives + 1;
|
|
extraLife = true;
|
|
}
|
|
return extraLife;
|
|
}
|
|
|
|
uint32 WetEngine::findPaletteIndexZones(uint32 id) {
|
|
switch (id) {
|
|
case 11:
|
|
return 237;
|
|
case 10:
|
|
return 239;
|
|
case 21:
|
|
return 240;
|
|
case 22:
|
|
return 237;
|
|
case 23:
|
|
return 238;
|
|
case 20:
|
|
return 239;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch (id / 10) {
|
|
case 3:
|
|
if (id == 30)
|
|
return 241;
|
|
else
|
|
return 237 + id % 10;
|
|
case 4:
|
|
if (id == 40)
|
|
return 241;
|
|
else
|
|
return 236 + id % 10;
|
|
case 5:
|
|
if (id == 50)
|
|
return 240;
|
|
else
|
|
return 237 + id % 10;
|
|
case 6:
|
|
if (id == 60)
|
|
return 238;
|
|
else
|
|
return 237;
|
|
default:
|
|
error("Invalid level id: %d", id);
|
|
}
|
|
}
|
|
|
|
void WetEngine::runBeforeArcade(ArcadeShooting *arc) {
|
|
_health = arc->health;
|
|
_maxHealth = _health;
|
|
resetStatistics();
|
|
_checkpoint = _currentLevel;
|
|
MVideo *video;
|
|
if (!isDemo() || ((_variant == "Demo" || _variant == "M&MCD") && _restoredContentEnabled)) {
|
|
|
|
saveProfile(_name, int(arc->id));
|
|
byte *palette;
|
|
Graphics::Surface *frame = decodeFrame("c_misc/zones.smk", (arc->id / 10 - 1) * 2, &palette);
|
|
loadPalette(palette, 0, 256);
|
|
free(palette);
|
|
byte red[3] = {0xff, 0x00, 0x00};
|
|
for (int i = 0; i < 5; i++)
|
|
loadPalette((byte *) &red, 237 + i, 1);
|
|
|
|
byte blue[3] = {0x00, 0x00, 0xff};
|
|
for (uint32 id = 10 * (arc->id / 10) + 1; id < arc->id; id++)
|
|
loadPalette((byte *) &blue, findPaletteIndexZones(id), 1);
|
|
|
|
byte green[3] = {0x00, 0xff, 0x00};
|
|
uint32 idx = findPaletteIndexZones(arc->id);
|
|
loadPalette((byte *) &green, idx, 1);
|
|
drawImage(*frame, 0, 0, false);
|
|
frame->free();
|
|
delete frame;
|
|
bool showedBriefing = false;
|
|
bool endedBriefing = false;
|
|
Common::Event event;
|
|
|
|
uint32 c = kHypnoColorGreen; // green
|
|
drawString("scifi08.fgx", Common::String::format("Lives : %d", _lives), 36, 2, 0, c);
|
|
while (!shouldQuit() && !endedBriefing) {
|
|
|
|
while (g_system->getEventManager()->pollEvent(event)) {
|
|
// Events
|
|
switch (event.type) {
|
|
|
|
case Common::EVENT_QUIT:
|
|
case Common::EVENT_RETURN_TO_LAUNCHER:
|
|
break;
|
|
|
|
case Common::EVENT_LBUTTONDOWN:
|
|
case Common::EVENT_KEYDOWN:
|
|
if (showedBriefing) {
|
|
endedBriefing = true;
|
|
break;
|
|
}
|
|
if (!arc->briefingVideo.empty()) {
|
|
Graphics::Surface *bframe = decodeFrame(arc->briefingVideo, 1, &palette);
|
|
loadPalette(palette, 0, 256);
|
|
free(palette);
|
|
video = new MVideo(arc->briefingVideo, Common::Point(44, 22), false, false, false);
|
|
runIntro(*video);
|
|
delete video;
|
|
bframe->free();
|
|
delete bframe;
|
|
}
|
|
showedBriefing = true;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
drawScreen();
|
|
g_system->delayMillis(10);
|
|
}
|
|
}
|
|
|
|
if (!arc->beforeVideo.empty()) {
|
|
video = new MVideo(arc->beforeVideo, Common::Point(0, 0), false, true, false);
|
|
runIntro(*video);
|
|
delete video;
|
|
}
|
|
|
|
if (arc->mode == "Y2" && !arc->additionalVideo.empty()) {
|
|
video = new MVideo(arc->additionalVideo, Common::Point(0, 0), false, true, false);
|
|
runIntro(*video);
|
|
delete video;
|
|
}
|
|
|
|
if (!arc->player.empty()) {
|
|
_playerFrames = decodeFrames(arc->player);
|
|
}
|
|
|
|
if (_variant == "EarlyDemo" && (arc->id == 31 || arc->id == 41)) {
|
|
int cutX = 36;
|
|
for (int i = 0; i < int(_playerFrames.size()); i++) {
|
|
Graphics::Surface *frame = _playerFrames[i];
|
|
Graphics::Surface *newFrame = new Graphics::Surface();
|
|
newFrame->create(320, 200, frame->format);
|
|
newFrame->fillRect(Common::Rect(0, 0, 320, 200), frame->format.ARGBToColor(0, 0, 0, 0));
|
|
newFrame->copyRectToSurfaceWithKey(*frame, 0, 0, Common::Rect(0, 0, 320, cutX), 0);
|
|
newFrame->copyRectToSurfaceWithKey(*frame, 0, 200 - (frame->h - cutX - 1), Common::Rect(0, cutX, 320, frame->h - 1), 0);
|
|
|
|
frame->free();
|
|
delete frame;
|
|
_playerFrames[i] = newFrame;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if (arc->mode == "Y4" || arc->mode == "Y5") { // These images are flipped, for some reason
|
|
for (Frames::iterator it = _playerFrames.begin(); it != _playerFrames.end(); ++it) {
|
|
for (int i = 0 ; i < (*it)->w ; i++)
|
|
for (int j = 0 ; j < (*it)->h/2 ; j++) {
|
|
uint32 p1 = (*it)->getPixel(i, j);
|
|
uint32 p2 = (*it)->getPixel(i, (*it)->h - j - 1);
|
|
(*it)->setPixel(i, j, p2);
|
|
(*it)->setPixel(i, (*it)->h - j - 1, p1);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
for (int i = 0; i < int(_playerFrames.size()); i++) {
|
|
if (_playerFrames[i]->getPixel(0, 0) == 255)
|
|
_playerFrameSeps.push_back(i);
|
|
else if (_playerFrames[i]->getPixel(0, 0) == 252)
|
|
_playerFrameSeps.push_back(i);
|
|
}
|
|
|
|
if (_playerFrameSeps.size() == 0) {
|
|
debugC(1, kHypnoDebugArcade, "No player separator frame found in %s! (size: %d)", arc->player.c_str(), _playerFrames.size());
|
|
} else
|
|
debugC(1, kHypnoDebugArcade, "Number of separator frames: %d", _playerFrameSeps.size());
|
|
|
|
_playerFrameStart = 0;
|
|
_playerFrameSep = _playerFrames.size();
|
|
|
|
if (_playerFrameSeps.size() > 0) {
|
|
_playerFrameSep = *_playerFrameSeps.begin();
|
|
_playerFrameSeps.pop_front();
|
|
}
|
|
|
|
if (_playerFrameSeps.size() > 0) {
|
|
_playerFrameEnd = *_playerFrameSeps.begin();
|
|
_playerFrameSeps.pop_front();
|
|
} else {
|
|
_playerFrameEnd = _playerFrames.size();
|
|
}
|
|
|
|
_playerFrameIdx = -1;
|
|
|
|
_ammo = 150;
|
|
_maxAmmo = 150;
|
|
_c33PlayerPosition = Common::Point(_screenW/2, _screenH/2);
|
|
|
|
if (arc->mode == "YT") {
|
|
_c33PlayerCursor = decodeFrames("c33/c33i2.smk");
|
|
_c33UseMouse = true;
|
|
_c33PlayerDirection.clear();
|
|
}
|
|
if (arc->mode == "Y3") {
|
|
bool started = startCountdown(420); // 7 minutes
|
|
if (!started)
|
|
error("Failed to start countdown in level %d!", arc->id);
|
|
} else
|
|
_timerStarted = false;
|
|
|
|
}
|
|
|
|
void WetEngine::pressedKey(const int keycode) {
|
|
if (keycode == Common::KEYCODE_c) {
|
|
_background->decoder->pauseVideo(true);
|
|
showCredits();
|
|
loadPalette(_currentPalette);
|
|
changeScreenMode("320x200");
|
|
_background->decoder->pauseVideo(false);
|
|
updateScreen(*_background);
|
|
drawScreen();
|
|
if (!_music.empty())
|
|
playSound(_music, 0, _musicRate); // restore music
|
|
} else if (keycode == Common::KEYCODE_s) { // Added for testing
|
|
if (_cheatsEnabled) {
|
|
_skipLevel = true;
|
|
}
|
|
} else if (keycode == Common::KEYCODE_k) { // Added for testing
|
|
_health = 0;
|
|
} else if (keycode == Common::KEYCODE_ESCAPE) {
|
|
openMainMenuDialog();
|
|
} else if (keycode == Common::KEYCODE_LEFT) {
|
|
if (_arcadeMode == "YT" && _c33PlayerPosition.x > 0) {
|
|
_c33UseMouse = false;
|
|
if (_c33PlayerDirection.size() < 3)
|
|
_c33PlayerDirection.push_back(kPlayerLeft);
|
|
}
|
|
} else if (keycode == Common::KEYCODE_DOWN) {
|
|
if (_arcadeMode == "YT" && _c33PlayerPosition.y < 130) { // Viewport value minus 30
|
|
_c33UseMouse = false;
|
|
if (_c33PlayerDirection.size() < 3)
|
|
_c33PlayerDirection.push_back(kPlayerBottom);
|
|
}
|
|
} else if (keycode == Common::KEYCODE_RIGHT) {
|
|
if (_arcadeMode == "YT" && _c33PlayerPosition.x < _screenW) {
|
|
_c33UseMouse = false;
|
|
if (_c33PlayerDirection.size() < 3)
|
|
_c33PlayerDirection.push_back(kPlayerRight);
|
|
}
|
|
} else if (keycode == Common::KEYCODE_UP) {
|
|
if (_arcadeMode == "YT" && _c33PlayerPosition.y > 0) {
|
|
_c33UseMouse = false;
|
|
if (_c33PlayerDirection.size() < 3)
|
|
_c33PlayerDirection.push_back(kPlayerTop);
|
|
}
|
|
}
|
|
}
|
|
|
|
Common::Point WetEngine::getPlayerPosition(bool needsUpdate) {
|
|
Common::Point mousePos = g_system->getEventManager()->getMousePos();
|
|
if (_arcadeMode == "YT") {
|
|
if (needsUpdate) {
|
|
if (!_c33UseMouse) {
|
|
disableCursor();
|
|
if (_c33PlayerDirection.size() == 0)
|
|
drawImage(*_c33PlayerCursor[10], _c33PlayerPosition.x - 10, _c33PlayerPosition.y, true);
|
|
else if (_c33PlayerDirection.front() == kPlayerRight) {
|
|
_c33PlayerPosition.x = _c33PlayerPosition.x + 4;
|
|
drawImage(*_c33PlayerCursor[4], _c33PlayerPosition.x - 10, _c33PlayerPosition.y, true);
|
|
} else if (_c33PlayerDirection.front() == kPlayerLeft) {
|
|
_c33PlayerPosition.x = _c33PlayerPosition.x - 4;
|
|
drawImage(*_c33PlayerCursor[8], _c33PlayerPosition.x - 10, _c33PlayerPosition.y, true);
|
|
} else if (_c33PlayerDirection.front() == kPlayerBottom) {
|
|
_c33PlayerPosition.y = _c33PlayerPosition.y + 4;
|
|
drawImage(*_c33PlayerCursor[12], _c33PlayerPosition.x - 10, _c33PlayerPosition.y, true);
|
|
} else if (_c33PlayerDirection.front() == kPlayerTop) {
|
|
_c33PlayerPosition.y = _c33PlayerPosition.y - 4;
|
|
drawImage(*_c33PlayerCursor[10], _c33PlayerPosition.x - 10, _c33PlayerPosition.y, true);
|
|
} else
|
|
error("Invalid condition in getPlayerPosition");
|
|
|
|
if (_c33PlayerDirection.size() > 0)
|
|
_c33PlayerDirection.pop_front();
|
|
} else {
|
|
Common::Point diff = mousePos - _c33PlayerPosition;
|
|
if (abs(diff.x) > 1 || abs(diff.y) > 1)
|
|
diff = diff / 10;
|
|
|
|
if (abs(diff.x) >= 10)
|
|
diff.x = (diff.x / abs(diff.x)) * 10;
|
|
|
|
if (abs(diff.y) >= 10)
|
|
diff.y = (diff.x / abs(diff.x)) * 10;
|
|
|
|
_c33PlayerPosition = _c33PlayerPosition + diff;
|
|
|
|
if (diff.x > 0 && abs(diff.x) > abs(diff.y))
|
|
drawImage(*_c33PlayerCursor[4], _c33PlayerPosition.x - 10, _c33PlayerPosition.y, true);
|
|
else if (diff.x < 0 && abs(diff.x) > abs(diff.y))
|
|
drawImage(*_c33PlayerCursor[8], _c33PlayerPosition.x - 10, _c33PlayerPosition.y, true);
|
|
else if (diff.y > 0)
|
|
drawImage(*_c33PlayerCursor[12], _c33PlayerPosition.x - 10, _c33PlayerPosition.y, true);
|
|
else
|
|
drawImage(*_c33PlayerCursor[10], _c33PlayerPosition.x - 10, _c33PlayerPosition.y, true);
|
|
}
|
|
}
|
|
uint32 c = _compositeSurface->getPixel(_c33PlayerPosition.x, _c33PlayerPosition.y);
|
|
if (c >= 225 && c <= 231) {
|
|
if (!_infiniteHealthCheat)
|
|
_health = _health - 1;
|
|
generateStaticEffect();
|
|
}
|
|
return _c33PlayerPosition;
|
|
}
|
|
return mousePos;
|
|
}
|
|
|
|
void WetEngine::drawCursorArcade(const Common::Point &mousePos) {
|
|
int i = detectTarget(mousePos);
|
|
if (_arcadeMode == "YT") {
|
|
if (_c33UseMouse)
|
|
changeCursor("arcade");
|
|
else
|
|
disableCursor();
|
|
return;
|
|
}
|
|
|
|
if (i >= 0)
|
|
changeCursor("target");
|
|
else
|
|
changeCursor("arcade");
|
|
}
|
|
|
|
bool WetEngine::clickedSecondaryShoot(const Common::Point &mousePos) {
|
|
if (_ammo <= 0)
|
|
return false;
|
|
|
|
if (!_infiniteAmmoCheat)
|
|
_ammo--;
|
|
incShotsFired();
|
|
return clickedPrimaryShoot(mousePos);
|
|
}
|
|
|
|
void WetEngine::missedTarget(Shoot *s, ArcadeShooting *arc) {
|
|
if (s->name == "SP_SWITCH_R" || s->name == "SP_SWITCH_L") {
|
|
_health = 0;
|
|
} else if (s->name == "SP_LIZARD1") {
|
|
if (!_infiniteHealthCheat)
|
|
_health = _health - 15;
|
|
_background->decoder->pauseVideo(true);
|
|
MVideo video(arc->additionalVideo, Common::Point(0, 0), false, true, false);
|
|
runIntro(video);
|
|
loadPalette(arc->backgroundPalette);
|
|
_background->decoder->pauseVideo(false);
|
|
updateScreen(*_background);
|
|
drawScreen();
|
|
} else if (s->name.hasPrefix("DOOR")) {
|
|
_health = 0;
|
|
_background->decoder->pauseVideo(true);
|
|
// In some levels, the hit boss video is used to store this ending
|
|
MVideo video(arc->hitBoss1Video, Common::Point(0, 0), false, true, false);
|
|
runIntro(video);
|
|
loadPalette(_currentPalette);
|
|
_background->decoder->pauseVideo(false);
|
|
updateScreen(*_background);
|
|
drawScreen();
|
|
_skipDefeatVideo = true;
|
|
} else if (s->attackFrames.empty()) {
|
|
if (!_infiniteHealthCheat)
|
|
_health = _health - s->attackWeight;
|
|
hitPlayer();
|
|
}
|
|
}
|
|
|
|
void WetEngine::missNoTarget(ArcadeShooting *arc) {
|
|
for (int i = _shoots.size() - 1; i >= 0; --i) {
|
|
Shoot *it = &_shoots[i];
|
|
if ((it->name == "SP_BOSS" || it->name == "SP_BOSS1") && !arc->missBoss1Video.empty()) {
|
|
_background->decoder->pauseVideo(true);
|
|
MVideo video(arc->missBoss1Video, Common::Point(0, 0), false, true, false);
|
|
disableCursor();
|
|
runIntro(video);
|
|
// Should be currentPalette?
|
|
loadPalette(arc->backgroundPalette);
|
|
_background->decoder->pauseVideo(false);
|
|
updateScreen(*_background);
|
|
drawScreen();
|
|
if (!_music.empty())
|
|
playSound(_music, 0, _musicRate); // restore music
|
|
break;
|
|
} else if (it->name == "SP_BOSS2" && !arc->missBoss2Video.empty()) {
|
|
_background->decoder->pauseVideo(true);
|
|
MVideo video(arc->missBoss2Video, Common::Point(0, 0), false, true, false);
|
|
disableCursor();
|
|
runIntro(video);
|
|
// Should be currentPalette?
|
|
loadPalette(arc->backgroundPalette);
|
|
_background->decoder->pauseVideo(false);
|
|
updateScreen(*_background);
|
|
drawScreen();
|
|
if (!_music.empty())
|
|
playSound(_music, 0, _musicRate); // restore music
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void WetEngine::generateStaticEffect() {
|
|
// random static
|
|
uint8 c = _compositeSurface->getPixel(150, 120); // some pixel in the middle
|
|
if (c != 0 && c != 254) {
|
|
for (int i = 0; i < _screenW; i++) {
|
|
for (int j = 50; j < 60; j++) {
|
|
c = _rnd->getRandomBit() ? 254 : 0;
|
|
_compositeSurface->setPixel(i, j, c);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < _screenW; i++) {
|
|
for (int j = 80; j < 90; j++) {
|
|
c = _rnd->getRandomBit() ? 254 : 0;
|
|
_compositeSurface->setPixel(i, j, c);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < _screenW; i++) {
|
|
for (int j = 120; j < 150; j++) {
|
|
c = _rnd->getRandomBit() ? 254 : 0;
|
|
_compositeSurface->setPixel(i, j, c);
|
|
}
|
|
}
|
|
drawScreen();
|
|
if (!_additionalSound.empty()) {
|
|
playSound(_soundPath + _additionalSound, 1, 11025);
|
|
}
|
|
}
|
|
}
|
|
|
|
void WetEngine::hitPlayer() {
|
|
if (_arcadeMode != "YT" && _arcadeMode != "Y1" && _arcadeMode != "Y2" && _arcadeMode != "Y3" && _arcadeMode != "Y4" && _arcadeMode != "Y5") {
|
|
assert( _playerFrameSep < (int)_playerFrames.size());
|
|
if (_playerFrameIdx < _playerFrameSep)
|
|
_playerFrameIdx = _playerFrameSep;
|
|
}
|
|
if (!_hitSound.empty()) {
|
|
playSound(_soundPath + _hitSound, 1, 11025);
|
|
}
|
|
}
|
|
|
|
Common::Point WetEngine::computeTargetPosition(const Common::Point &mousePos) {
|
|
if (_arcadeMode == "YT") {
|
|
return Common::Point(mousePos.x, mousePos.y - 20);
|
|
}
|
|
return mousePos;
|
|
}
|
|
|
|
void WetEngine::drawShoot(const Common::Point &mousePos) {
|
|
uint32 c = kHypnoColorYellow;
|
|
|
|
if (_arcadeMode == "YT") {
|
|
_compositeSurface->drawLine(mousePos.x, mousePos.y - 20, mousePos.x + 5, mousePos.y, c);
|
|
_compositeSurface->drawLine(mousePos.x, mousePos.y - 20, mousePos.x + 5, mousePos.y, c);
|
|
|
|
_compositeSurface->drawLine(mousePos.x, mousePos.y - 20, mousePos.x - 5, mousePos.y, c);
|
|
_compositeSurface->drawLine(mousePos.x, mousePos.y - 20, mousePos.x - 5, mousePos.y, c);
|
|
} else if (_arcadeMode == "Y4") {
|
|
_compositeSurface->drawLine(_screenW/2 - 50, _screenH, mousePos.x, mousePos.y, c);
|
|
_compositeSurface->drawLine(_screenW/2 - 50, _screenH, mousePos.x - 1, mousePos.y, c);
|
|
|
|
_compositeSurface->drawLine(_screenW/2 + 50, _screenH, mousePos.x, mousePos.y, c);
|
|
_compositeSurface->drawLine(_screenW/2 + 50, _screenH, mousePos.x - 1, mousePos.y, c);
|
|
} else {
|
|
_compositeSurface->drawLine(0, _screenH, mousePos.x, mousePos.y, c);
|
|
_compositeSurface->drawLine(0, _screenH, mousePos.x - 1, mousePos.y, c);
|
|
_compositeSurface->drawLine(0, _screenH, mousePos.x - 2, mousePos.y, c);
|
|
|
|
_compositeSurface->drawLine(_screenW, _screenH, mousePos.x, mousePos.y, c);
|
|
_compositeSurface->drawLine(_screenW, _screenH, mousePos.x - 1, mousePos.y, c);
|
|
_compositeSurface->drawLine(_screenW, _screenH, mousePos.x - 2, mousePos.y, c);
|
|
}
|
|
|
|
playSound(_soundPath + _shootSound, 1);
|
|
|
|
if (_arcadeMode == "Y4") {
|
|
if (mousePos.x <= 25)
|
|
_playerFrameIdx = 10;
|
|
else if (mousePos.x <= 50)
|
|
_playerFrameIdx = 12;
|
|
else if (mousePos.x >= 295)
|
|
_playerFrameIdx = 18;
|
|
else if (mousePos.x >= 270)
|
|
_playerFrameIdx = 16;
|
|
else
|
|
_playerFrameIdx = 14;
|
|
|
|
drawImage(*_playerFrames[_playerFrameIdx], 0, 200 - _playerFrames[_playerFrameIdx]->h, true);
|
|
}
|
|
}
|
|
|
|
void WetEngine::drawPlayer() {
|
|
uint8 segmentType = _segments[_segmentIdx].type;
|
|
if (segmentType == 0xc5 || segmentType == 0xc2 || segmentType == 0xcc)
|
|
if (_background->decoder->getCurFrame() % 3 > 0) // Avoid flashing too much
|
|
drawString("block05.fgx", _directionString, 113, 13, 80, kHypnoColorCyan);
|
|
|
|
// TARGET ACQUIRED frame
|
|
uint32 c = kHypnoColorGreen; // green
|
|
_compositeSurface->drawLine(113, 1, 119, 1, c);
|
|
_compositeSurface->drawLine(200, 1, 206, 1, c);
|
|
|
|
_compositeSurface->drawLine(113, 1, 113, 9, c);
|
|
_compositeSurface->drawLine(206, 1, 206, 9, c);
|
|
|
|
_compositeSurface->drawLine(113, 9, 119, 9, c);
|
|
_compositeSurface->drawLine(200, 9, 206, 9, c);
|
|
|
|
if (_timerStarted) {
|
|
assert(_arcadeMode == "Y3");
|
|
c = kHypnoColorYellow;
|
|
uint32 minutes = _countdown / 60;
|
|
uint32 seconds = _countdown % 60;
|
|
drawString("block05.fgx", Common::String::format("CLOCK %02d:%02d", minutes, seconds), 19, 11, 0, c);
|
|
|
|
const chapterEntry *entry = _chapterTable[_levelId];
|
|
Common::Point ep(entry->energyPos[0], entry->energyPos[1]);
|
|
|
|
Common::Rect r = Common::Rect(ep.x - 2, ep.y + 6, ep.x + 69, ep.y + 15);
|
|
_compositeSurface->frameRect(r, kHypnoColorGreen);
|
|
|
|
}
|
|
|
|
c = kHypnoColorRed; // red ?
|
|
Common::Point mousePos = g_system->getEventManager()->getMousePos();
|
|
int i = detectTarget(mousePos);
|
|
if (i >= 0)
|
|
drawString("block05.fgx", _targetString.c_str(), 116, 3, 80, c);
|
|
|
|
if (_arcadeMode == "Y1" || _arcadeMode == "Y3")
|
|
return;
|
|
|
|
_playerFrameIdx++;
|
|
if (_playerFrameIdx == _playerFrameSep || _playerFrameIdx >= _playerFrameEnd) {
|
|
_playerFrameIdx = _playerFrameStart;
|
|
}
|
|
|
|
if (_arcadeMode == "Y5") {
|
|
int x = mousePos.x / (_screenW / 3);
|
|
int y = mousePos.y / (_screenH / 3);
|
|
_playerFrameIdx = 2 * (x + 3*y) + 1;
|
|
} else if (_arcadeMode == "Y4") {
|
|
if (mousePos.x <= 25)
|
|
_playerFrameIdx = 0;
|
|
else if (mousePos.x <= 50)
|
|
_playerFrameIdx = 2;
|
|
else if (mousePos.x >= 295)
|
|
_playerFrameIdx = 8;
|
|
else if (mousePos.x >= 270)
|
|
_playerFrameIdx = 6;
|
|
else
|
|
_playerFrameIdx = 4;
|
|
}
|
|
|
|
|
|
int offset = 0;
|
|
// Ugly, but seems to be necessary
|
|
if (_levelId == 31 && _variant != "EarlyDemo")
|
|
offset = 2;
|
|
else if (_levelId == 52)
|
|
offset = 2;
|
|
|
|
drawImage(*_playerFrames[_playerFrameIdx], 0, 200 - _playerFrames[_playerFrameIdx]->h + offset, true);
|
|
}
|
|
|
|
void WetEngine::drawHealth() {
|
|
uint32 c = kHypnoColorYellow;
|
|
int p = (100 * _health) / _maxHealth;
|
|
int s = _score;
|
|
int mo = _objKillsCount[_objIdx];
|
|
int mm = _objKillsRequired[_objIdx];
|
|
if (_playerFrameIdx < _playerFrameSep) {
|
|
const chapterEntry *entry = _chapterTable[_levelId];
|
|
Common::Point ep(entry->energyPos[0], entry->energyPos[1]);
|
|
Common::Point sp(entry->scorePos[0], entry->scorePos[1]);
|
|
Common::Point op(entry->objectivesPos[0], entry->objectivesPos[1]);
|
|
Common::String healthFormat = _healthString + " %d%%";
|
|
drawString("block05.fgx", Common::String::format(healthFormat.c_str(), p), ep.x, ep.y, 65, c);
|
|
Common::String scoreFormat = _scoreString + " %04d";
|
|
Common::String moFormat = _objString + " %d/%d";
|
|
|
|
if (_arcadeMode == "Y1" || _arcadeMode == "Y3" || _arcadeMode == "Y4" || _arcadeMode == "Y5") {
|
|
Common::Rect r;
|
|
r = Common::Rect(ep.x - 2, ep.y - 2, ep.x + 69, sp.y + 7);
|
|
_compositeSurface->frameRect(r, kHypnoColorGreen);
|
|
|
|
r = Common::Rect(sp.x - 2, sp.y - 2, sp.x + 74, sp.y + 7);
|
|
_compositeSurface->frameRect(r, kHypnoColorGreen);
|
|
|
|
r = Common::Rect(op.x - 2, op.y - 2, op.x + 74, op.y + 7);
|
|
_compositeSurface->frameRect(r, kHypnoColorGreen);
|
|
|
|
scoreFormat = _scoreString + " %04d";
|
|
moFormat = _objString + " %d/%d";
|
|
}
|
|
|
|
drawString("block05.fgx", Common::String::format(scoreFormat.c_str(), s), sp.x, sp.y, 72, c);
|
|
if (op.x > 0 && op.y > 0)
|
|
drawString("block05.fgx", Common::String::format(moFormat.c_str(), mo, mm), op.x, op.y, 60, c);
|
|
}
|
|
}
|
|
|
|
void WetEngine::drawAmmo() {
|
|
const chapterEntry *entry = _chapterTable[_levelId];
|
|
if (entry->ammoPos[0] == 0 && entry->ammoPos[1] == 0)
|
|
return;
|
|
|
|
if (_playerFrameIdx > _playerFrameSep) // Player was hit
|
|
return;
|
|
|
|
int d = (13 * (_maxAmmo - _ammo) / _maxAmmo);
|
|
if (d >= 13)
|
|
return;
|
|
Common::Point p(entry->ammoPos[0], entry->ammoPos[1]);
|
|
int ao = entry->ammoOffset;
|
|
Common::Rect r;
|
|
if (_arcadeMode == "Y1" || _arcadeMode == "Y3" || _arcadeMode == "Y4" || _arcadeMode == "Y5") {
|
|
r = Common::Rect(p.x - 1, p.y - 1, p.x + 16, p.y + 14);
|
|
_compositeSurface->frameRect(r, kHypnoColorGreen);
|
|
}
|
|
|
|
if (_levelId / 10 == 5 && _arcadeMode != "Y5") {
|
|
r = Common::Rect(p.x, p.y + d, p.x + 13, p.y + 13);
|
|
_compositeSurface->fillRect(r, kHypnoColorWhiteOrBlue); // blue
|
|
|
|
if (ao > 0) {
|
|
r = Common::Rect(p.x + ao, p.y + d, p.x + 13 + ao, p.y + 13);
|
|
_compositeSurface->fillRect(r, kHypnoColorWhiteOrBlue); // blue
|
|
}
|
|
} else {
|
|
r = Common::Rect(p.x, p.y + d, p.x + 15, p.y + 13);
|
|
_compositeSurface->fillRect(r, kHypnoColorWhiteOrBlue); // blue
|
|
|
|
if (ao > 0) {
|
|
r = Common::Rect(p.x + ao, p.y + d, p.x + 15 + ao, p.y + 13);
|
|
_compositeSurface->fillRect(r, kHypnoColorWhiteOrBlue); // blue
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
byte *WetEngine::getTargetColor(Common::String name, int levelId) {
|
|
if (name == "BOSS1" || name == "BOSS2" || name == "BOSS3" || name == "BOSS4")
|
|
return getPalette(kHypnoColorGreen);
|
|
|
|
const chapterEntry *entry = _chapterTable[levelId];
|
|
if (entry->targetColor < 0)
|
|
error ("No target color specified for level %d", levelId);
|
|
return getPalette(entry->targetColor);
|
|
}
|
|
|
|
bool WetEngine::checkRButtonUp() {
|
|
return _rButtonUp;
|
|
}
|
|
|
|
void WetEngine::setRButtonUp(const bool val) {
|
|
_rButtonUp = val;
|
|
}
|
|
|
|
} // End of namespace Hypno
|