aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/EventMapper.cpp6
-rw-r--r--engines/agos/midi.cpp4
-rw-r--r--engines/avalanche/animation.cpp15
-rw-r--r--engines/avalanche/animation.h5
-rw-r--r--engines/avalanche/avalanche.cpp17
-rw-r--r--engines/avalanche/avalanche.h6
-rw-r--r--engines/avalanche/avalot.cpp27
-rw-r--r--engines/avalanche/dialogs.cpp15
-rw-r--r--engines/avalanche/dropdown.cpp2
-rw-r--r--engines/avalanche/enums.h1
-rw-r--r--engines/avalanche/ghostroom.cpp39
-rw-r--r--engines/avalanche/ghostroom.h4
-rw-r--r--engines/avalanche/graphics.cpp83
-rw-r--r--engines/avalanche/graphics.h8
-rw-r--r--engines/avalanche/highscore.cpp110
-rw-r--r--engines/avalanche/highscore.h59
-rw-r--r--engines/avalanche/module.mk3
-rw-r--r--engines/avalanche/parser.cpp4
-rw-r--r--engines/avalanche/parser.h7
-rw-r--r--engines/fullpipe/constants.h1
-rw-r--r--engines/fullpipe/fullpipe.cpp4
-rw-r--r--engines/fullpipe/fullpipe.h1
-rw-r--r--engines/fullpipe/gfx.cpp11
-rw-r--r--engines/fullpipe/messagehandlers.cpp4
-rw-r--r--engines/fullpipe/modal.cpp278
-rw-r--r--engines/fullpipe/modal.h32
-rw-r--r--engines/fullpipe/scenes.cpp26
-rw-r--r--engines/fullpipe/scenes.h2
-rw-r--r--engines/fullpipe/scenes/scene29.cpp2
-rw-r--r--engines/fullpipe/statics.cpp165
-rw-r--r--engines/fullpipe/statics.h1
-rw-r--r--engines/neverhood/modules/module2200.cpp2
-rw-r--r--engines/neverhood/modules/module2300.cpp28
-rw-r--r--engines/neverhood/modules/module2300.h4
-rw-r--r--engines/neverhood/modules/module3000.cpp49
-rw-r--r--engines/neverhood/modules/module3000.h4
-rw-r--r--engines/pegasus/items/item.cpp14
-rw-r--r--engines/pegasus/items/item.h7
-rw-r--r--engines/pegasus/items/itemlist.cpp5
-rw-r--r--engines/pegasus/items/itemlist.h1
-rw-r--r--engines/pegasus/neighborhood/caldoria/caldoria.cpp6
-rw-r--r--engines/pegasus/neighborhood/mars/mars.cpp4
-rw-r--r--engines/pegasus/neighborhood/tsa/fulltsa.cpp1
-rw-r--r--engines/pegasus/neighborhood/tsa/tinytsa.cpp1
-rw-r--r--engines/pegasus/pegasus.cpp40
-rw-r--r--engines/pegasus/pegasus.h1
-rw-r--r--engines/wintermute/base/font/base_font_truetype.cpp2
-rw-r--r--engines/wintermute/video/video_theora_player.cpp1
48 files changed, 922 insertions, 190 deletions
diff --git a/common/EventMapper.cpp b/common/EventMapper.cpp
index 84774742c6..30896d7514 100644
--- a/common/EventMapper.cpp
+++ b/common/EventMapper.cpp
@@ -37,11 +37,17 @@ List<Event> DefaultEventMapper::mapEvent(const Event &ev, EventSource *source) {
#ifdef ENABLE_VKEYBD
else if (ev.kbd.keycode == KEYCODE_F7 && ev.kbd.hasFlags(0)) {
mappedEvent.type = EVENT_VIRTUAL_KEYBOARD;
+
+ // Avoid blocking F7 events from engine.
+ addDelayedEvent(100, ev);
}
#endif
#ifdef ENABLE_KEYMAPPER
else if (ev.kbd.keycode == KEYCODE_F8 && ev.kbd.hasFlags(0)) {
mappedEvent.type = EVENT_KEYMAPPER_REMAP;
+
+ // Avoid blocking F8 events from engine.
+ addDelayedEvent(100, ev);
}
#endif
}
diff --git a/engines/agos/midi.cpp b/engines/agos/midi.cpp
index c26fbe3331..392ee08ea1 100644
--- a/engines/agos/midi.cpp
+++ b/engines/agos/midi.cpp
@@ -235,6 +235,10 @@ void MidiPlayer::startTrack(int track) {
_music.parser = parser; // That plugs the power cord into the wall
} else if (_music.parser) {
if (!_music.parser->setTrack(track)) {
+ // The Roland MT32 music in Simon the Sorcerer 2
+ // is missing the extra tracks in many scenes,
+ // like the introduction sequence.
+ stop();
return;
}
_currentTrack = (byte)track;
diff --git a/engines/avalanche/animation.cpp b/engines/avalanche/animation.cpp
index 86ca4c8541..451b4a1c68 100644
--- a/engines/avalanche/animation.cpp
+++ b/engines/avalanche/animation.cpp
@@ -764,7 +764,7 @@ void Animation::catacombMove(byte ped) {
spr1->init(5, true); // ...Load Geida.
appearPed(1, geidaPed(ped));
spr1->_callEachStepFl = true;
- spr1->_eachStepProc = kProcGeida;
+ spr1->_eachStepProc = kProcFollowAvvy;
}
}
@@ -1121,7 +1121,7 @@ void Animation::spin(Direction dir, byte &tripnum) {
}
}
-void Animation::geidaProcs(byte tripnum) {
+void Animation::follow(byte tripnum) {
AnimationType *tripSpr = _sprites[tripnum];
AnimationType *avvy = _sprites[0];
@@ -1132,14 +1132,14 @@ void Animation::geidaProcs(byte tripnum) {
}
if (tripSpr->_y < (avvy->_y - 2)) {
- // Geida is further from the screen than Avvy.
+ // The following NPC is further from the screen than Avvy.
spin(kDirDown, tripnum);
tripSpr->_moveY = 1;
tripSpr->_moveX = 0;
takeAStep(tripnum);
return;
} else if (tripSpr->_y > (avvy->_y + 2)) {
- // Avvy is further from the screen than Geida.
+ // Avvy is further from the screen than the following NPC.
spin(kDirUp, tripnum);
tripSpr->_moveY = -1;
tripSpr->_moveX = 0;
@@ -1205,8 +1205,9 @@ void Animation::drawSprites() {
* @remarks Originally called 'trippancy_link'
*/
void Animation::animLink() {
- if (_vm->_dropdown->isActive() || _vm->_seeScroll)
+ if (_vm->_dropdown->isActive() || !_vm->_animationsEnabled)
return;
+
for (int16 i = 0; i < kSpriteNumbMax; i++) {
AnimationType *curSpr = _sprites[i];
if (curSpr->_quick && curSpr->_visible)
@@ -1235,8 +1236,8 @@ void Animation::animLink() {
case kProcGrabAvvy :
grabAvvy(i);
break;
- case kProcGeida :
- geidaProcs(i);
+ case kProcFollowAvvy :
+ follow(i);
break;
default:
break;
diff --git a/engines/avalanche/animation.h b/engines/avalanche/animation.h
index 375d117893..d1ee4a3ebd 100644
--- a/engines/avalanche/animation.h
+++ b/engines/avalanche/animation.h
@@ -102,9 +102,8 @@ public:
kProcBackAndForth,
kProcFaceAvvy,
kProcArrow,
- kProcSpludwick, // Unused
kProcGrabAvvy,
- kProcGeida // Spludwick uses it as well for homing! TODO: Unify it with kProcSpludwick.
+ kProcFollowAvvy
};
AnimationType *_sprites[kSpriteNumbMax];
@@ -167,7 +166,7 @@ private:
// Movements for Homing NPCs: Spludwick and Geida.
void spin(Direction dir, byte &tripnum);
void takeAStep(byte &tripnum);
- void geidaProcs(byte tripnum);
+ void follow(byte tripnum);
void drawSprites();
};
diff --git a/engines/avalanche/avalanche.cpp b/engines/avalanche/avalanche.cpp
index 1bc4c5348d..6cfe4dfdb6 100644
--- a/engines/avalanche/avalanche.cpp
+++ b/engines/avalanche/avalanche.cpp
@@ -57,6 +57,7 @@ AvalancheEngine::AvalancheEngine(OSystem *syst, const AvalancheGameDescription *
_nim = nullptr;
_ghostroom = nullptr;
_help = nullptr;
+ _highscore = nullptr;
_platform = gd->desc.platform;
initVariables();
@@ -81,6 +82,7 @@ AvalancheEngine::~AvalancheEngine() {
delete _nim;
delete _ghostroom;
delete _help;
+ delete _highscore;
for (int i = 0; i < 31; i++) {
for (int j = 0; j < 2; j++) {
@@ -142,7 +144,7 @@ void AvalancheEngine::initVariables() {
_letMeOut = false;
_thinks = 2;
_thinkThing = true;
- _seeScroll = false;
+ _animationsEnabled = true;
_currentMouse = 177;
_holdLeftMouse = false;
@@ -165,6 +167,7 @@ Common::ErrorCode AvalancheEngine::initialize() {
_nim = new Nim(this);
_ghostroom = new GhostRoom(this);
_help = new Help(this);
+ _highscore = new HighScore(this);
_graphics->init();
_dialogs->init();
@@ -200,7 +203,7 @@ void AvalancheEngine::synchronize(Common::Serializer &sz) {
sz.syncAsByte(_carryNum);
for (int i = 0; i < kObjectNum; i++)
sz.syncAsByte(_objects[i]);
- sz.syncAsSint16LE(_dnascore);
+ sz.syncAsSint16LE(_score);
sz.syncAsSint32LE(_money);
sz.syncAsByte(_room);
if (sz.isSaving())
@@ -336,8 +339,8 @@ void AvalancheEngine::synchronize(Common::Serializer &sz) {
}
-bool AvalancheEngine::canSaveGameStateCurrently() { // TODO: Refine these!!!
- return (!_seeScroll && _alive);
+bool AvalancheEngine::canSaveGameStateCurrently() {
+ return (_animationsEnabled && _alive);
}
Common::Error AvalancheEngine::saveGameState(int slot, const Common::String &desc) {
@@ -381,8 +384,8 @@ Common::String AvalancheEngine::getSaveFileName(const int slot) {
return Common::String::format("%s.%03d", _targetName.c_str(), slot);
}
-bool AvalancheEngine::canLoadGameStateCurrently() { // TODO: Refine these!!!
- return (!_seeScroll);
+bool AvalancheEngine::canLoadGameStateCurrently() {
+ return (_animationsEnabled);
}
Common::Error AvalancheEngine::loadGameState(int slot) {
@@ -432,7 +435,7 @@ bool AvalancheEngine::loadGame(const int16 slot) {
_isLoaded = true;
- _seeScroll = true; // This prevents display of the new sprites before the new picture is loaded.
+ _animationsEnabled = false;
if (_holdTheDawn) {
_holdTheDawn = false;
diff --git a/engines/avalanche/avalanche.h b/engines/avalanche/avalanche.h
index 146065ad63..6eb5e675cc 100644
--- a/engines/avalanche/avalanche.h
+++ b/engines/avalanche/avalanche.h
@@ -46,6 +46,7 @@
#include "avalanche/help.h"
#include "avalanche/shootemup.h"
#include "avalanche/mainmenu.h"
+#include "avalanche/highscore.h"
#include "common/serializer.h"
@@ -91,6 +92,7 @@ public:
Nim *_nim;
GhostRoom *_ghostroom;
Help *_help;
+ HighScore *_highscore;
OSystem *_system;
@@ -150,7 +152,7 @@ public:
// Former DNA structure
byte _carryNum; // How many objects you're carrying...
bool _objects[kObjectNum]; // ...and which ones they are.
- int16 _dnascore; // your score, of course
+ int16 _score; // your score, of course
int32 _money; // your current amount of dosh
Room _room; // your current room
bool _wonNim; // Have you *won* Nim? (That's harder.)
@@ -210,7 +212,7 @@ public:
bool _letMeOut;
byte _thinks;
bool _thinkThing;
- bool _seeScroll; // TODO: maybe this means we're interacting with the toolbar / a scroll?
+ bool _animationsEnabled; // If set to TRUE, it stops the animation system working. This prevents display of the new sprites before the new picture is loaded or during the display of a scroll. Original name: seescroll.
char _objectList[10];
// Called .free() for them in ~Gyro().
diff --git a/engines/avalanche/avalot.cpp b/engines/avalanche/avalot.cpp
index 1cb2f186a5..c8f5599687 100644
--- a/engines/avalanche/avalot.cpp
+++ b/engines/avalanche/avalot.cpp
@@ -249,8 +249,6 @@ void AvalancheEngine::runAvalot() {
_system->delayMillis(55 - delay); // Replaces slowdown(); 55 comes from 18.2 Hz (B Flight).
};
- warning("STUB: run()");
-
_closing->exitGame();
}
@@ -464,7 +462,7 @@ void AvalancheEngine::findPeople(byte room) {
void AvalancheEngine::exitRoom(byte x) {
_sound->stopSound();
_background->release();
- _seeScroll = true; // This stops the trippancy system working over the length of this procedure.
+ _animationsEnabled = false;
switch (x) {
case kRoomSpludwicks:
@@ -487,7 +485,7 @@ void AvalancheEngine::exitRoom(byte x) {
}
_interrogation = 0; // Leaving the room cancels all the questions automatically.
- _seeScroll = false; // Now it can work again!
+ _animationsEnabled = true;
_lastRoom = _room;
if (_room != kRoomMap)
@@ -534,11 +532,11 @@ void AvalancheEngine::putGeidaAt(byte whichPed, byte ped) {
spr1->init(5, false); // load Geida
_animation->appearPed(1, whichPed);
spr1->_callEachStepFl = true;
- spr1->_eachStepProc = Animation::kProcGeida;
+ spr1->_eachStepProc = Animation::kProcFollowAvvy;
}
void AvalancheEngine::enterRoom(Room roomId, byte ped) {
- _seeScroll = true; // This stops the trippancy system working over the length of this procedure.
+ _animationsEnabled = false;
findPeople(roomId);
_room = roomId;
@@ -619,7 +617,7 @@ void AvalancheEngine::enterRoom(Room roomId, byte ped) {
}
spr1->_callEachStepFl = true;
- spr1->_eachStepProc = Animation::kProcGeida;
+ spr1->_eachStepProc = Animation::kProcFollowAvvy;
} else
_whereIs[kPeopleSpludwick - 150] = kRoomNowhere;
break;
@@ -922,7 +920,7 @@ void AvalancheEngine::enterRoom(Room roomId, byte ped) {
break;
}
- _seeScroll = false; // Now it can work again!
+ _animationsEnabled = true;
}
void AvalancheEngine::thinkAbout(byte object, bool type) {
@@ -957,7 +955,7 @@ void AvalancheEngine::drawToolbar() {
}
void AvalancheEngine::drawScore() {
- uint16 score = _dnascore;
+ uint16 score = _score;
int8 numbers[3] = {0, 0, 0};
for (int i = 0; i < 2; i++) {
byte divisor = 1;
@@ -983,15 +981,14 @@ void AvalancheEngine::drawScore() {
void AvalancheEngine::incScore(byte num) {
for (int i = 1; i <= num; i++) {
- _dnascore++;
+ _score++;
if (_soundFx) {
for (int j = 1; j <= 97; j++)
- // Length os 2 is a guess, the original doesn't have a delay specified
- _sound->playNote(177 + _dnascore * 3, 2);
+ // Length of 2 is a guess, the original doesn't have a delay specified
+ _sound->playNote(177 + _score * 3, 2);
}
}
- warning("STUB: points()");
drawScore();
}
@@ -1336,7 +1333,7 @@ void AvalancheEngine::resetVariables() {
for (int i = 0; i < kObjectNum; i++)
_objects[i] = false;
- _dnascore = 0;
+ _score = 0;
_money = 0;
_room = kRoomNowhere;
_saveNum = 0;
@@ -1442,7 +1439,7 @@ void AvalancheEngine::newGame() {
_thinkThing = true;
_thinks = 2;
refreshObjectList();
- _seeScroll = false;
+ _animationsEnabled = true;
avvy->appear(300, 117, kDirRight); // Needed to initialize Avalot.
//for (gd = 0; gd <= 30; gd++) for (gm = 0; gm <= 1; gm++) also[gd][gm] = nil;
diff --git a/engines/avalanche/dialogs.cpp b/engines/avalanche/dialogs.cpp
index b7b03e86dc..e843d17c5b 100644
--- a/engines/avalanche/dialogs.cpp
+++ b/engines/avalanche/dialogs.cpp
@@ -157,7 +157,7 @@ void Dialogs::scrollModeNormal() {
Common::String e = "(c) 1994";
setReadyLight(3);
- _vm->_seeScroll = true;
+ _vm->_animationsEnabled = false;
_vm->_graphics->loadMouse(kCurFletch);
_vm->_graphics->saveScreen();
@@ -216,10 +216,8 @@ void Dialogs::scrollModeNormal() {
#endif
setReadyLight(0);
- _vm->_seeScroll = false;
+ _vm->_animationsEnabled = true;
_vm->_holdLeftMouse = false; // Used in Lucerna::checkclick().
-
- warning("STUB: Scrolls::scrollModeNormal()");
}
/**
@@ -290,7 +288,7 @@ bool Dialogs::theyMatch(TuneType &played) {
*/
void Dialogs::scrollModeMusic() {
setReadyLight(3);
- _vm->_seeScroll = true;
+ _vm->_animationsEnabled = false;
CursorMan.showMouse(false);
_vm->_graphics->loadMouse(kCurFletch);
@@ -299,7 +297,7 @@ void Dialogs::scrollModeMusic() {
played[i] = kPitchInvalid;
int8 lastOne = -1, thisOne = -1; // Invalid values.
- _vm->_seeScroll = true;
+ _vm->_animationsEnabled = false;
_vm->_graphics->saveScreen();
_vm->_graphics->showScroll();
@@ -393,7 +391,7 @@ void Dialogs::scrollModeMusic() {
_vm->_graphics->restoreScreen();
_vm->_graphics->removeBackup();
- _vm->_seeScroll = false;
+ _vm->_animationsEnabled = true;
CursorMan.showMouse(true);
}
@@ -646,9 +644,6 @@ void Dialogs::solidify(byte n) {
* 'calldriver' and 'display' by using Common::String instead of a private buffer.
*/
void Dialogs::displayText(Common::String text) {
-// bool was_virtual; // Was the mouse cursor virtual on entry to this proc?
- warning("STUB: Scrolls::calldrivers()");
-
_vm->_sound->stopSound();
setReadyLight(0);
diff --git a/engines/avalanche/dropdown.cpp b/engines/avalanche/dropdown.cpp
index 7c0529811e..97adfc2581 100644
--- a/engines/avalanche/dropdown.cpp
+++ b/engines/avalanche/dropdown.cpp
@@ -678,7 +678,7 @@ void DropDownMenu::setup() {
_menuBar.draw();
}
-void DropDownMenu::update() { // TODO: Optimize it ASAP!!! It really needs it...
+void DropDownMenu::update() {
_vm->_graphics->saveScreen();
Common::Point cursorPos = _vm->getMousePos();
diff --git a/engines/avalanche/enums.h b/engines/avalanche/enums.h
index 998c96a131..0ba39321bc 100644
--- a/engines/avalanche/enums.h
+++ b/engines/avalanche/enums.h
@@ -30,6 +30,7 @@
namespace Avalanche {
+enum MonsterType { kMonsterTypeGhost, kMonsterTypeGlerk };
enum Flavour { kFlavourEga, kFlavourBgi, kFlavourNatural, kFlavourTwo, kFlavourOne };
diff --git a/engines/avalanche/ghostroom.cpp b/engines/avalanche/ghostroom.cpp
index 1419a0cbab..16c79fdee0 100644
--- a/engines/avalanche/ghostroom.cpp
+++ b/engines/avalanche/ghostroom.cpp
@@ -70,6 +70,30 @@ GhostRoom::~GhostRoom() {
for (int j = 0; j < 6; j++)
_greldet[j][i].free();
}
+
+ if (_wasLoaded) {
+ for (int i = 0; i < 5; i++) {
+ for (int j = 0; j < 2; j++) {
+ for (int y = 0; y < 66; y++) {
+ delete[] _ghost[i][j][y];
+ }
+ delete[] _ghost[i][j];
+ }
+ delete[] _ghost[i];
+ }
+ delete[] _ghost;
+
+ for (int i = 0; i < 6; i++) {
+ for (int j = 0; j < 4; j++) {
+ for (int y = 0; y < 35; y++) {
+ delete[] _glerk[i][j][y];
+ }
+ delete[] _glerk[i][j];
+ }
+ delete[] _glerk[i];
+ }
+ delete[] _glerk;
+ }
}
void GhostRoom::wait(uint16 howLong) {
@@ -141,9 +165,13 @@ void GhostRoom::loadPictures() {
file.seek(44);
// Initializing ghost's array.
+ _ghost = new byte***[5];
for (int i = 0; i < 5; i++) {
+ _ghost[i] = new byte**[2];
for (int j = 0; j < 2; j++) {
+ _ghost[i][j] = new byte*[66];
for (int y = 0; y < 66; y++) {
+ _ghost[i][j][y] = new byte[26];
for (int x = 0; x < 26; x++)
_ghost[i][j][y][x] = 0;
}
@@ -171,11 +199,14 @@ void GhostRoom::loadPictures() {
for (int i = 0; i < 3; i++)
_bat[i] = _vm->_graphics->ghostLoadPicture(file, dummyCoord);
-
// Initializing glerk's array.
+ _glerk = new byte***[6];
for (int i = 0; i < 6; i++) {
+ _glerk[i] = new byte**[4];
for (int j = 0; j < 4; j++) {
+ _glerk[i][j] = new byte*[35];
for (int y = 0; y < 35; y++) {
+ _glerk[i][j][y] = new byte[9];
for (int x = 0; x < 9; x++)
_glerk[i][j][y][x] = 0;
}
@@ -245,7 +276,7 @@ void GhostRoom::run() {
if (_glerkStage > 25)
break;
- _vm->_graphics->ghostDrawGlerk(_glerk[kGlerkFade[_glerkStage]], 456, 14);
+ _vm->_graphics->ghostDrawMonster(_glerk[kGlerkFade[_glerkStage]], 456, 14, kMonsterTypeGlerk);
_glerkStage++;
}
@@ -263,7 +294,7 @@ void GhostRoom::run() {
// Here comes the descending ghost:
for (int y = -64; y <= 103; y++) {
- _vm->_graphics->ghostDrawGhost(_ghost[1 + (abs(y / 7) % 2) * 3], 0, y);
+ _vm->_graphics->ghostDrawMonster(_ghost[1 + (abs(y / 7) % 2) * 3], 0, y, kMonsterTypeGhost);
if (y > 0)
_vm->_graphics->drawFilledRectangle(Common::Rect(0, y - 1, 26 * 8 + 1, y + 1), kColorBlack);
_vm->_graphics->refreshScreen();
@@ -277,7 +308,7 @@ void GhostRoom::run() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 5; j++) {
_vm->_graphics->drawFilledRectangle(Common::Rect(0, 96, 26 * 8, 170), kColorBlack);
- _vm->_graphics->ghostDrawGhost(_ghost[kWaveOrder[j]], 0, 96 + kAdjustment[j]);
+ _vm->_graphics->ghostDrawMonster(_ghost[kWaveOrder[j]], 0, 96 + kAdjustment[j], kMonsterTypeGhost);
_aarghCount++;
diff --git a/engines/avalanche/ghostroom.h b/engines/avalanche/ghostroom.h
index ebb02f7aac..4c659128ce 100644
--- a/engines/avalanche/ghostroom.h
+++ b/engines/avalanche/ghostroom.h
@@ -58,11 +58,11 @@ private:
static const byte kGreldetFade[18];
Common::Point dummyCoord;
- byte _ghost[5][2][66][26];
+ byte ****_ghost;// [5][2][66][26]
Graphics::Surface _eyes[2];
Graphics::Surface _exclamation;
Graphics::Surface _bat[3];
- byte _glerk[6][4][35][9];
+ byte ****_glerk; // [6][4][35][9]
Graphics::Surface _aargh[6];
Common::Point _aarghWhere[6];
Graphics::Surface _greenEyes[5];
diff --git a/engines/avalanche/graphics.cpp b/engines/avalanche/graphics.cpp
index ae53f3e034..513cd72c8c 100644
--- a/engines/avalanche/graphics.cpp
+++ b/engines/avalanche/graphics.cpp
@@ -527,64 +527,65 @@ void GraphicManager::nimFree() {
_nimLogo.free();
}
-void GraphicManager::ghostDrawGhost(byte ghostArr[2][66][26], uint16 destX, int16 destY) {
+void GraphicManager::ghostDrawMonster(byte ***picture, uint16 destX, int16 destY, MonsterType type) {
+ uint16 height = 0;
+ uint16 width = 0;
+ // Only for the Ghost:
const byte kPlaneToUse[4] = { 0, 0, 0, 1 };
- // Constants from the original code:
- uint16 height = 66;
- const uint16 width = 26 * 8;
-
- // We have to mess around with the coords and the sizes since
- // the ghost isn't always placed fully on the screen.
int yStart = 0;
- if (destY < 0) {
- yStart = abs(destY);
- height -= yStart;
- destY = 0;
- }
-
- Graphics::Surface ghostPic;
- ghostPic.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
-
- for (int y = 0; y < height; y++) {
- for (int plane = 0; plane < 4; plane++) {
- for (uint16 x = 0; x < width / 8; x ++) {
- byte pixel = ghostArr[kPlaneToUse[plane]][y + yStart][x];
- for (int bit = 0; bit < 8; bit++) {
- byte pixelBit = (pixel >> bit) & 1;
- *(byte *)ghostPic.getBasePtr(x * 8 + 7 - bit, y) += (pixelBit << plane);
- }
- }
+
+ // Constants from the original code:
+ switch (type) {
+ case kMonsterTypeGhost:
+ height = 66;
+ width = 208; // 26 * 8
+
+ // We have to mess around with the coords and the sizes since
+ // the ghost isn't always placed fully on the screen.
+ if (destY < 0) {
+ yStart = abs(destY);
+ height -= yStart;
+ destY = 0;
}
+ break;
+ case kMonsterTypeGlerk:
+ height = 35;
+ width = 72; // 9 * 8
+ break;
+ default:
+ break;
}
- drawPicture(_surface, ghostPic, destX, destY);
-
- ghostPic.free();
-}
-
-void GraphicManager::ghostDrawGlerk(byte glerkArr[4][35][9], uint16 destX, uint16 destY) {
- // Constants from the original code:
- const uint16 height = 35;
- const uint16 width = 9 * 8;
-
- Graphics::Surface glerkPic;
- glerkPic.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+ Graphics::Surface monsterPicture;
+ monsterPicture.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
for (int y = 0; y < height; y++) {
for (int plane = 0; plane < 4; plane++) {
for (uint16 x = 0; x < width / 8; x++) {
- byte pixel = glerkArr[plane][y][x];
+ byte pixel = 0;
+
+ switch (type) {
+ case kMonsterTypeGhost:
+ pixel = picture[kPlaneToUse[plane]][y + yStart][x];
+ break;
+ case kMonsterTypeGlerk:
+ pixel = picture[plane][y][x];
+ break;
+ default:
+ break;
+ }
+
for (int bit = 0; bit < 8; bit++) {
byte pixelBit = (pixel >> bit) & 1;
- *(byte *)glerkPic.getBasePtr(x * 8 + 7 - bit, y) += (pixelBit << plane);
+ *(byte *)monsterPicture.getBasePtr(x * 8 + 7 - bit, y) += (pixelBit << plane);
}
}
}
}
- drawPicture(_surface, glerkPic, destX, destY);
+ drawPicture(_surface, monsterPicture, destX, destY);
- glerkPic.free();
+ monsterPicture.free();
}
/**
diff --git a/engines/avalanche/graphics.h b/engines/avalanche/graphics.h
index 7e0ed64b5f..bd8fc6c8ff 100644
--- a/engines/avalanche/graphics.h
+++ b/engines/avalanche/graphics.h
@@ -97,8 +97,7 @@ public:
void drawWinningPic();
// Ghostroom's functions:
- void ghostDrawGhost(byte ghostArr[2][66][26], uint16 destX, int16 destY); // Very similar to loadPictureSign(). TODO: Unify the two later if possible.
- void ghostDrawGlerk(byte glerkArr[4][35][9], uint16 destX, uint16 destY); // Very similar to ghostDrawGhost(), but not enough to unify the two.
+ void ghostDrawMonster(byte ***picture, uint16 destX, int16 destY, MonsterType type);
Graphics::Surface ghostLoadPicture(Common::File &file, Common::Point &coord);
void ghostDrawPicture(const Graphics::Surface &picture, uint16 destX, uint16 destY);
void ghostDrawBackgroundItems(Common::File &file);
@@ -106,7 +105,7 @@ public:
// Help's function:
void helpDrawButton(int y, byte which);
void helpDrawHighlight(byte which, Color color);
- void helpDrawBigText(const Common::String text, int16 x, int16 y, Color color); // Very similar to drawText. TODO: Try to unify the two.
+ void helpDrawBigText(const Common::String text, int16 x, int16 y, Color color);
// Shoot em' up's functions:
void seuDrawTitle();
@@ -199,12 +198,11 @@ private:
Graphics::Surface loadPictureSign(Common::File &file, uint16 width, uint16 height); // Reads a tricky type of picture used for the "game over"/"about" scrolls and in the mini-game Nim.
void drawText(Graphics::Surface &surface, const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color);
- void drawBigText(Graphics::Surface &surface, const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color); // Very similar to drawText. TODO: Try to unify the two.
+ void drawBigText(Graphics::Surface &surface, const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color);
void drawPicture(Graphics::Surface &target, const Graphics::Surface picture, uint16 destX, uint16 destY);
// Taken from Free Pascal's Procedure InternalEllipseDefault. Used to replace Pascal's procedure arc.
// Returns the end point of the arc. (Needed in Clock.)
- // TODO: Make it more accurate later.
Common::Point drawArc(Graphics::Surface &surface, int16 x, int16 y, int16 stAngle, int16 endAngle, uint16 radius, Color color);
};
diff --git a/engines/avalanche/highscore.cpp b/engines/avalanche/highscore.cpp
new file mode 100644
index 0000000000..bbe92e7f8a
--- /dev/null
+++ b/engines/avalanche/highscore.cpp
@@ -0,0 +1,110 @@
+/* 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 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.
+*
+*/
+
+/*
+* This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+* Copyright (c) 1994-1995 Mike: Mark and Thomas Thurman.
+*/
+
+#include "avalanche/avalanche.h"
+#include "avalanche/highscore.h"
+
+#include "common/savefile.h"
+
+namespace Avalanche {
+
+HighScore::HighScore(AvalancheEngine *vm) {
+ _vm = vm;
+}
+
+void HighScore::displayHighScores() {
+ warning("STUB: HighScore::displayHighScores(");
+}
+
+void HighScore::saveHighScores() {
+ int firstSmaller = 0;
+ while ((_data[firstSmaller]._score >= _vm->_score) && (firstSmaller < 12))
+ firstSmaller++;
+
+ if (firstSmaller < 12) {
+ // Shift all the lower scores down a space:
+ for (int i = firstSmaller; i < 11; i++)
+ _data[i + 1] = _data[i];
+ // Set the new high score:
+ _data[firstSmaller]._name = "Player"; // TODO: Come up with something for that. In the original it wasn't implemented at all...
+ _data[firstSmaller]._rank = _vm->_parser->rank();
+ _data[firstSmaller]._score = _vm->_score;
+ }
+
+ Common::OutSaveFile *f = g_system->getSavefileManager()->openForSaving("scores.avd");
+ if (!f) {
+ warning("Can't create file 'scores.avd', high scores are not saved.");
+ return;
+ }
+ Common::Serializer sz(NULL, f);
+ syncHighScores(sz);
+ f->finalize();
+ delete f;
+}
+
+void HighScore::loadHighScroes() {
+ Common::File file;
+ if (!file.exists("scores.avd")) {
+ produceDefaultHighScores();
+ } else {
+ Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading("scores.avd");
+ if (!f)
+ return;
+ Common::Serializer sz(f, NULL);
+ syncHighScores(sz);
+ delete f;
+ }
+}
+
+void HighScore::produceDefaultHighScores() {
+ for (int i = 0; i < 12; i++) {
+ _data[i]._score = 32 - (i + 1) * 2;
+ _data[i]._rank = "...";
+ }
+ _data[0]._name = "Mike";
+ _data[1]._name = "Liz";
+ _data[2]._name = "Thomas";
+ _data[3]._name = "Mark";
+ _data[4]._name = "Mandy";
+ _data[5]._name = "Andrew";
+ _data[6]._name = "Lucy Tryphena";
+ _data[7]._name = "Tammy the dog";
+ _data[8]._name = "Avaricius";
+ _data[9]._name = "Spellchick";
+ _data[10]._name = "Caddelli";
+ _data[11]._name = "Spludwick";
+}
+
+void HighScore::syncHighScores(Common::Serializer &sz) {
+ for (int i = 0; i < 12; i++) {
+ sz.syncString(_data[i]._name);
+ sz.syncAsUint16LE(_data[i]._score);
+ sz.syncString(_data[i]._rank);
+ }
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/highscore.h b/engines/avalanche/highscore.h
new file mode 100644
index 0000000000..de7ec36ed5
--- /dev/null
+++ b/engines/avalanche/highscore.h
@@ -0,0 +1,59 @@
+/* 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 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.
+*
+*/
+
+/*
+* This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+* Copyright (c) 1994-1995 Mike: Mark and Thomas Thurman.
+*/
+
+#ifndef AVALANCHE_HIGHSCORE_H
+#define AVALANCHE_HIGHSCORE_H
+
+namespace Avalanche {
+class AvalancheEngine;
+
+struct HighScoreData {
+ Common::String _name;
+ uint16 _score;
+ Common::String _rank;
+};
+
+class HighScore {
+public:
+ HighScore(AvalancheEngine *vm);
+
+ void displayHighScores();
+ void saveHighScores();
+ void loadHighScroes();
+
+private:
+ AvalancheEngine *_vm;
+
+ HighScoreData _data[12];
+
+ void produceDefaultHighScores();
+ void syncHighScores(Common::Serializer &sz);
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_HIGHSCORE_H
diff --git a/engines/avalanche/module.mk b/engines/avalanche/module.mk
index d31fd0d91a..29bc039b42 100644
--- a/engines/avalanche/module.mk
+++ b/engines/avalanche/module.mk
@@ -20,7 +20,8 @@ MODULE_OBJS = \
ghostroom.o \
help.o \
shootemup.o \
- mainmenu.o
+ mainmenu.o \
+ highscore.o
# This module can be built as a plugin
ifeq ($(ENABLE_AVALANCHE), DYNAMIC_PLUGIN)
diff --git a/engines/avalanche/parser.cpp b/engines/avalanche/parser.cpp
index da365fe93f..b152747ab0 100644
--- a/engines/avalanche/parser.cpp
+++ b/engines/avalanche/parser.cpp
@@ -602,7 +602,7 @@ Common::String Parser::rank() {
};
for (int i = 0; i < 8; i++) {
- if ((_vm->_dnascore >= ranks[i]._score) && (_vm->_dnascore < ranks[i + 1]._score))
+ if ((_vm->_score >= ranks[i]._score) && (_vm->_score < ranks[i + 1]._score))
return Common::String(ranks[i]._title);
}
return "";
@@ -2306,7 +2306,7 @@ void Parser::doThat() {
break;
case kVerbCodeScore: {
Common::String tmpStr = Common::String::format("Your score is %d,%c%cout of a possible 128.%c%c " \
- "This gives you a rank of %s.%c%c%s", _vm->_dnascore, kControlCenter, kControlNewLine, kControlNewLine,
+ "This gives you a rank of %s.%c%c%s", _vm->_score, kControlCenter, kControlNewLine, kControlNewLine,
kControlNewLine, rank().c_str(), kControlNewLine, kControlNewLine, totalTime().c_str());
_vm->_dialogs->displayText(tmpStr);
}
diff --git a/engines/avalanche/parser.h b/engines/avalanche/parser.h
index 6a15fb2387..6133c41442 100644
--- a/engines/avalanche/parser.h
+++ b/engines/avalanche/parser.h
@@ -72,13 +72,11 @@ public:
byte _wearing; // what you're wearing
Parser(AvalancheEngine *vm);
-
void init();
void parse();
void doThat();
void verbOpt(byte verb, Common::String &answer, char &ansKey);
void drink();
-
void handleInputText(const Common::Event &event);
void handleBackspace();
void handleReturn();
@@ -89,7 +87,7 @@ public:
void tryDropdown();
int16 getPos(const Common::String &crit, const Common::String &src);
void doVerb(VerbCode id);
-
+ Common::String rank();
void resetVariables();
void synchronize(Common::Serializer &sz);
@@ -112,10 +110,7 @@ private:
byte wordNum(Common::String word);
void replace(Common::String oldChars, byte newChar);
-
- Common::String rank();
Common::String totalTime();
-
void clearWords();
void cheatParse(Common::String codes);
void stripPunctuation(Common::String &word);
diff --git a/engines/fullpipe/constants.h b/engines/fullpipe/constants.h
index 741a55f74c..c0b7ed906c 100644
--- a/engines/fullpipe/constants.h
+++ b/engines/fullpipe/constants.h
@@ -267,6 +267,7 @@ namespace Fullpipe {
#define TrubaUp 680
// Main Menu
+#define PIC_MEX_BGR 5300
#define PIC_MNU_AUTHORS_L 4624
#define PIC_MNU_CONTINUE_L 4626
#define PIC_MNU_DEBUG_L 4632
diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp
index 2b4c90b576..c6cc270b67 100644
--- a/engines/fullpipe/fullpipe.cpp
+++ b/engines/fullpipe/fullpipe.cpp
@@ -191,6 +191,10 @@ void FullpipeEngine::initialize() {
_mgm = new MGM;
}
+void FullpipeEngine::restartGame() {
+ warning("STUB: FullpipeEngine::restartGame()");
+}
+
Common::Error FullpipeEngine::run() {
const Graphics::PixelFormat format(2, 5, 6, 5, 0, 11, 5, 0, 0);
// Initialize backend
diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
index 11d7585fa2..9ba5da3726 100644
--- a/engines/fullpipe/fullpipe.h
+++ b/engines/fullpipe/fullpipe.h
@@ -91,6 +91,7 @@ public:
GUI::Debugger *getDebugger() { return _console; }
void initialize();
+ void restartGame();
void setMusicAllowed(int val) { _musicAllowed = val; }
diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index 137af86f48..26ac4ab824 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -90,7 +90,16 @@ Background::Background() {
}
Background::~Background() {
- warning("STUB: Background::~Background()");
+ _picObjList.clear();
+
+ for (int i = 0; i < _bigPictureArray1Count; i++) {
+ for (int j = 0; j < _bigPictureArray2Count; j++)
+ delete _bigPictureArray[i][j];
+
+ free(_bigPictureArray[i]);
+ }
+
+ free(_bigPictureArray);
}
bool Background::load(MfcArchive &file) {
diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp
index b8e7b5c1db..17af2bf4fd 100644
--- a/engines/fullpipe/messagehandlers.cpp
+++ b/engines/fullpipe/messagehandlers.cpp
@@ -528,9 +528,9 @@ int global_messageHandler4(ExCommand *cmd) {
ExCommand2 *cmd2 = (ExCommand2 *)cmd;
if (cmd->_excFlags & 1) {
- ani->startAnimSteps(cmd->_messageNum, 0, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize >> 3, flags);
+ ani->startAnimSteps(cmd->_messageNum, 0, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize, flags);
} else {
- ani->startAnimSteps(cmd->_messageNum, cmd->_parId, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize >> 3, flags);
+ ani->startAnimSteps(cmd->_messageNum, cmd->_parId, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize, flags);
}
break;
}
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index 833d47fde1..5cdc449d91 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -752,11 +752,12 @@ void ModalCredits::update() {
ModalMainMenu::ModalMainMenu() {
_areas.clear();
- _mfield_2C = 0;
- _mfield_C = 0;
+ _lastArea = 0;
+ _hoverAreaId = 0;
_mfield_34 = 0;
_scene = g_fp->accessScene(SC_MAINMENU);
- _mfield_50 = 0;
+ _debugKeyCount = 0;
+ _sliderOffset = 0;
_screct.left = g_fp->_sceneRect.left;
_screct.top = g_fp->_sceneRect.top;
_screct.right = g_fp->_sceneRect.right;
@@ -780,7 +781,7 @@ ModalMainMenu::ModalMainMenu() {
area = new MenuArea();
area->picIdL = PIC_MNU_EXIT_L;
area->picObjD = 0;
- area->picObjL = _scene->getPictureObjectById(PIC_MNU_EXIT_L, 0);
+ area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
area->picObjL->_flags &= 0xFFFB;
_areas.push_back(area);
@@ -837,7 +838,7 @@ ModalMainMenu::ModalMainMenu() {
area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
area->picObjL->_flags &= 0xFFFB;
_areas.push_back(area);
- _musicSliderIdx = _areas.size();
+ _musicSliderIdx = _areas.size() - 1;
if (g_fp->_mainMenu_debugEnabled)
enableDebugMenuButton();
@@ -845,14 +846,267 @@ ModalMainMenu::ModalMainMenu() {
setSliderPos();
}
+void ModalMainMenu::update() {
+ _scene->draw();
+}
+
+bool ModalMainMenu::handleMessage(ExCommand *message) {
+ if (message->_messageKind != 17)
+ return false;
+
+ Common::Point point;
+
+ if (message->_messageNum == 29) {
+ point.x = message->_x;
+ point.y = message->_y;
+
+ int numarea = checkHover(point);
+
+ if (numarea >= 0) {
+ if (numarea == _menuSliderIdx) {
+ _lastArea = _areas[_menuSliderIdx];
+ _sliderOffset = _lastArea->picObjL->_ox - point.x;
+
+ return false;
+ }
+
+ if (numarea == _musicSliderIdx) {
+ _lastArea = _areas[_musicSliderIdx];
+ _sliderOffset = _lastArea->picObjL->_ox - point.x;
+
+ return false;
+ }
+
+ _hoverAreaId = _areas[numarea]->picIdL;
+ }
+
+ return false;
+ }
+
+ if (message->_messageNum == 30) {
+ if (_lastArea)
+ _lastArea = 0;
+
+ return false;
+ }
+
+ if (message->_messageNum != 36)
+ return false;
+
+ if (message->_keyCode == 27)
+ _hoverAreaId = PIC_MNU_CONTINUE_L;
+ else
+ enableDebugMenu(message->_keyCode);
+
+ return false;
+}
+
+bool ModalMainMenu::init(int counterdiff) {
+ switch (_hoverAreaId) {
+ case PIC_MNU_RESTART_L:
+ g_fp->restartGame();
+
+ if (this == g_fp->_modalObject)
+ return false;
+
+ delete this;
+ break;
+
+ case PIC_MNU_EXIT_L:
+ {
+ ModalQuery *mq = new ModalQuery();
+
+ g_fp->_modalObject = mq;
+
+ mq->_parentObj = this;
+ mq->create(_scene, PIC_MEX_BGR);
+
+ _hoverAreaId = 0;
+
+ return true;
+ }
+
+ case PIC_MNU_DEBUG_L:
+ g_fp->_gameLoader->unloadScene(SC_MAINMENU);
+ g_fp->_sceneRect = _screct;
+
+ if (!g_fp->_currentScene)
+ error("ModalMainMenu::init: Bad state");
+
+ g_fp->_currentScene->_x = _bgX;
+ g_fp->_currentScene->_y = _bgY;
+
+ g_fp->_gameLoader->preloadScene(g_fp->_currentScene->_sceneId, SC_DBGMENU);
+
+ return false;
+
+ case PIC_MNU_CONTINUE_L:
+ if (!_mfield_34) {
+ g_fp->_gameLoader->unloadScene(SC_MAINMENU);
+ g_fp->_sceneRect = _screct;
+
+ if (g_fp->_currentScene) {
+ g_fp->_currentScene->_x = _bgX;
+ g_fp->_currentScene->_y = _bgY;
+ }
+
+ return false;
+ }
+
+ g_fp->restartGame();
+
+ if (this == g_fp->_modalObject)
+ return false;
+
+ delete this;
+ break;
+
+ case PIC_MNU_AUTHORS_L:
+ g_fp->_modalObject = new ModalCredits();
+ g_fp->_modalObject->_parentObj = this;
+
+ _hoverAreaId = 0;
+
+ return true;
+
+ case PIC_MNU_SAVE_L:
+ case PIC_MNU_LOAD_L:
+ {
+ ModalSaveGame *sg = new ModalSaveGame();
+
+ g_fp->_modalObject = sg;
+ g_fp->_modalObject->_parentObj = _parentObj;
+
+ int mode = 0;
+ if (_hoverAreaId == PIC_MNU_SAVE_L)
+ mode = 1;
+
+ sg->setup(g_fp->accessScene(SC_MAINMENU), mode);
+ sg->setScene(g_fp->accessScene(SC_MAINMENU));
+
+ sg->_rect = _screct;
+ sg->_oldBgX = _bgX;
+ sg->_oldBgY = _bgY;
+
+ delete this;
+ }
+
+ break;
+
+ default:
+ if (_lastArea) {
+ updateSliderPos();
+ } else {
+ g_fp->_cursorId = PIC_CSR_DEFAULT;
+
+ int idx = checkHover(g_fp->_mouseScreenPos);
+
+ if (idx < 0)
+ goto LABEL_40;
+
+ g_fp->_cursorId = PIC_CSR_DEFAULT;
+
+ if (idx != this->_menuSliderIdx && idx != this->_musicSliderIdx )
+ goto LABEL_40;
+ }
+
+ g_fp->_cursorId = PIC_CSR_LIFT;
+
+ LABEL_40:
+ g_fp->setCursor(g_fp->_cursorId);
+
+ updateVolume();
+
+ return true;
+ }
+
+ return true;
+}
+
+void ModalMainMenu::updateVolume() {
+ warning("STUB: ModalMainMenu::updateVolume()");
+}
+
+void ModalMainMenu::updateSliderPos() {
+ warning("STUB: ModalMainMenu::updateSliderPos()");
+}
+
+int ModalMainMenu::checkHover(Common::Point &point) {
+ for (uint i = 0; i < _areas.size(); i++) {
+ if (_areas[i]->picObjL->isPixelHitAtPos(point.x, point.y)) {
+ _areas[i]->picObjL->_flags |= 4;
+
+ return i;
+ } else {
+ _areas[i]->picObjL->_flags &= 0xFFFB;
+ }
+ }
+
+ if (isOverArea(_areas[_menuSliderIdx]->picObjL, &point)) {
+ _areas[_menuSliderIdx]->picObjL->_flags |= 4;
+
+ return _menuSliderIdx;
+ }
+
+ if (isOverArea(_areas[_musicSliderIdx]->picObjL, &point)) {
+ _areas[_musicSliderIdx]->picObjL->_flags |= 4;
+
+ return _musicSliderIdx;
+ }
+
+ return -1;
+}
+
+bool ModalMainMenu::isOverArea(PictureObject *obj, Common::Point *point) {
+ Common::Point p;
+
+ obj->getDimensions(&p);
+
+ int left = point->x - 8;
+ int right = point->x + 12;
+ int down = point->y - 11;
+ int up = point->y + 9;
+
+ if (left >= obj->_ox && right < obj->_ox + p.x && down >= obj->_oy && up < obj->_oy + p.y)
+ return true;
+
+ return false;
+}
+
bool ModalMainMenu::isSaveAllowed() {
warning("STUB: ModalMainMenu::isSaveAllowed()");
return true;
}
+void ModalMainMenu::enableDebugMenu(char c) {
+ const char deb[] = "DEBUGER";
+
+ if (c == deb[_debugKeyCount]) {
+ _debugKeyCount++;
+
+ if (deb[_debugKeyCount] )
+ return;
+
+ enableDebugMenuButton();
+ }
+
+ _debugKeyCount = 0;
+}
+
void ModalMainMenu::enableDebugMenuButton() {
- warning("STUB: ModalMainMenu::enableDebugMenuButton()");
+ MenuArea *area;
+
+ for (uint i = 0; i < _areas.size(); i++)
+ if (_areas[i]->picIdL == PIC_MNU_DEBUG_L)
+ return;
+
+ area = new MenuArea();
+ area->picIdL = PIC_MNU_DEBUG_L;
+ area->picObjD = 0;
+ area->picObjL = _scene->getPictureObjectById(area->picIdL, 0);
+ area->picObjL->_flags &= 0xFFFB;
+ _areas.push_back(area);
}
void ModalMainMenu::setSliderPos() {
@@ -920,6 +1174,18 @@ void ModalHelp::launch() {
}
}
+void ModalQuery::create(Scene *sc, int picId) {
+ warning("STUB: ModalQuery::create()");
+}
+
+void ModalSaveGame::setScene(Scene *sc) {
+ warning("STUB: ModalSaveGame::setScene()");
+}
+
+void ModalSaveGame::setup(Scene *sc, int mode) {
+ warning("STUB: ModalSaveGame::setup()");
+}
+
void FullpipeEngine::openHelp() {
if (!_modalObject) {
ModalHelp *help = new ModalHelp;
diff --git a/engines/fullpipe/modal.h b/engines/fullpipe/modal.h
index 532d145c2c..78ddf71f54 100644
--- a/engines/fullpipe/modal.h
+++ b/engines/fullpipe/modal.h
@@ -156,32 +156,37 @@ struct MenuArea {
class ModalMainMenu : public BaseModalObject {
public:
Scene *_scene;
- int _mfield_C;
+ int _hoverAreaId;
Common::Array<MenuArea *> _areas;
int _menuSliderIdx;
int _musicSliderIdx;
- int _mfield_2C;
- int _mfield_30;
+ MenuArea *_lastArea;
+ int _sliderOffset;
int _mfield_34;
Common::Rect _screct;
int _bgX;
int _bgY;
- int _mfield_50;
+ int _debugKeyCount;
public:
ModalMainMenu();
virtual ~ModalMainMenu() {}
virtual bool pollEvent() { return true; }
- virtual bool handleMessage(ExCommand *message) { return false; }
- virtual bool init(int counterdiff) { return true; }
- virtual void update() {}
+ virtual bool handleMessage(ExCommand *message);
+ virtual bool init(int counterdiff);
+ virtual void update();
virtual void saveload() {}
private:
bool isSaveAllowed();
void enableDebugMenuButton();
void setSliderPos();
+ void enableDebugMenu(char c);
+ int checkHover(Common::Point &point);
+ void updateVolume();
+ void updateSliderPos();
+ bool isOverArea(PictureObject *obj, Common::Point *point);
};
class ModalHelp : public BaseModalObject {
@@ -208,7 +213,7 @@ public:
class ModalQuery : public BaseModalObject {
public:
- ModalQuery();
+ ModalQuery() {}
virtual ~ModalQuery() {}
virtual bool pollEvent() { return true; }
@@ -216,11 +221,13 @@ public:
virtual bool init(int counterdiff) { return true; }
virtual void update() {}
virtual void saveload() {}
+
+ void create(Scene *sc, int picId);
};
class ModalSaveGame : public BaseModalObject {
public:
- ModalSaveGame();
+ ModalSaveGame() {}
virtual ~ModalSaveGame() {}
virtual bool pollEvent() { return true; }
@@ -228,6 +235,13 @@ public:
virtual bool init(int counterdiff) { return true; }
virtual void update() {}
virtual void saveload() {}
+
+ void setScene(Scene *sc);
+ void setup(Scene *sc, int mode);
+
+ Common::Rect _rect;
+ int _oldBgX;
+ int _oldBgY;
};
diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp
index 3abb03d1ae..47c6a3c8cd 100644
--- a/engines/fullpipe/scenes.cpp
+++ b/engines/fullpipe/scenes.cpp
@@ -1465,8 +1465,30 @@ Ball *BallChain::sub04(Ball *ballP, Ball *ballN) {
return pTail;
}
-void BallChain::sub05(Ball *ball) {
- warning("STUB: BallChain::sub05");
+void BallChain::removeBall(Ball *ball) {
+ if (ball == pHead)
+ pHead = ball->p0;
+ else
+ ball->p1->p0 = ball->p0;
+
+ if (ball == field_8)
+ field_8 = ball->p1;
+ else
+ ball->p0->p1 = ball->p1;
+
+ ball->p0 = pTail;
+ pTail = ball;
+
+ numBalls--;
+
+ if (!numBalls) {
+ numBalls = 0;
+ pTail = 0;
+ field_8 = 0;
+ pHead = 0;
+ free(cPlex);
+ cPlex = 0;
+ }
}
diff --git a/engines/fullpipe/scenes.h b/engines/fullpipe/scenes.h
index 517576c6f3..0b7c4e7c8f 100644
--- a/engines/fullpipe/scenes.h
+++ b/engines/fullpipe/scenes.h
@@ -232,7 +232,7 @@ struct BallChain {
void init(Ball **ball);
Ball *sub04(Ball *ballP, Ball *ballN);
- void sub05(Ball *ball);
+ void removeBall(Ball *ball);
void reset() { pHead = 0; pTail = 0; field_8 = 0; numBalls = 0; free(cPlex); cPlex = 0; cPlexLen = 0; }
};
diff --git a/engines/fullpipe/scenes/scene29.cpp b/engines/fullpipe/scenes/scene29.cpp
index dbd753a133..2d5127137d 100644
--- a/engines/fullpipe/scenes/scene29.cpp
+++ b/engines/fullpipe/scenes/scene29.cpp
@@ -641,7 +641,7 @@ void sceneHandler29_ballHitCheck() {
g_vars->scene29_redBalls.field_8 = newball;
- g_vars->scene29_flyingRedBalls.sub05(ball);
+ g_vars->scene29_flyingRedBalls.removeBall(ball);
sceneHandler29_manHit();
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 75c1c7d1ea..a3a160b5b2 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -105,6 +105,19 @@ bool StepArray::gotoNextPoint() {
}
}
+void StepArray::insertPoints(Common::Point **points, int pointsCount) {
+ if (_currPointIndex + pointsCount >= _pointsCount)
+ _points = (Common::Point **)realloc(_points, sizeof(Common::Point *) * (_currPointIndex + pointsCount));
+
+ _maxPointIndex = _currPointIndex + pointsCount;
+
+ for (int i = 0; i < pointsCount; i++) {
+ _points[_currPointIndex + i] = new Common::Point;
+
+ *_points[_currPointIndex + i] = *points[i];
+ }
+}
+
StaticANIObject::StaticANIObject() {
_shadowsOn = 1;
_field_30 = 0;
@@ -330,7 +343,35 @@ bool StaticANIObject::trySetMessageQueue(int msgNum, int qId) {
}
void StaticANIObject::startMQIfIdle(int qId, int flag) {
- warning("STUB: StaticANIObject::startMQIfIdle()");
+ MessageQueue *msg = g_fp->_currentScene->getMessageQueueById(qId);
+
+ if (msg && isIdle() && !(_flags & 0x100)) {
+ MessageQueue *mq = new MessageQueue(msg, 0, 0);
+
+ mq->setFlags(mq->getFlags() | flag);
+
+ ExCommand *ex = mq->getExCommandByIndex(0);
+
+ if (ex) {
+ while (ex->_messageKind != 1 || ex->_parentId != _id) {
+ ex->_parId = 0;
+ ex->_excFlags |= 2;
+ ex->handleMessage();
+
+ mq->deleteExCommandByIndex(0, 0);
+
+ ex = mq->getExCommandByIndex(0);
+
+ if (!ex)
+ return;
+ }
+
+ if (ex) {
+ startAnim(ex->_messageNum, mq->_id, -1);
+ mq->deleteExCommandByIndex(0, 1);
+ }
+ }
+ }
}
bool StaticANIObject::isIdle() {
@@ -1060,7 +1101,47 @@ void StaticANIObject::show1(int x, int y, int movId, int mqId) {
}
void StaticANIObject::show2(int x, int y, int movementId, int mqId) {
- warning("STUB: StaticANIObject::show2(%d, %d, %d, %d)", x, y, movementId, mqId);
+ if (movementId == -1) {
+ _flags |= 4u;
+ return;
+ }
+
+ if (!_messageQueueId) {
+ _messageQueueId = mqId;
+
+ Movement *mov = getMovementById(movementId);
+
+ if (mov) {
+ _statics = mov->_staticsObj1;
+ _movement = mov;
+ mov->gotoLastFrame();
+ mov->setOXY(x, y);
+ mov->gotoFirstFrame();
+
+ Common::Point point;
+
+ mov->getCurrDynamicPhaseXY(point);
+ _statics->_x = mov->_ox - point.x - mov->_mx;
+ _statics->_y = mov->_oy - point.y - mov->_my;
+
+ _statics->getSomeXY(point);
+ _flags |= 4;
+ _ox = _statics->_x + point.x;
+ _oy = _statics->_y + point.y;
+
+ if (mov->_currMovement) {
+ _flags |= 8;
+ } else {
+ if (_flags & 8)
+ _flags ^= 8;
+ }
+
+ if (_flags & 1)
+ _flags ^= 1;
+
+ _flags |= 0x20;
+ }
+ }
}
void StaticANIObject::playIdle() {
@@ -1069,7 +1150,85 @@ void StaticANIObject::playIdle() {
}
void StaticANIObject::startAnimSteps(int movementId, int messageQueueId, int x, int y, Common::Point **points, int pointsCount, int someDynamicPhaseIndex) {
- warning("STUB: StaticANIObject::startAnimSteps()");
+ Movement *mov = 0;
+
+ if (!(_flags & 0x80)) {
+ if (!_messageQueueId)
+ for (uint i = 0; i < _movements.size(); i++) {
+ if (((Movement *)_movements[i])->_id == movementId) {
+ mov = (Movement *)_movements[i];
+ break;
+ }
+ }
+ }
+
+ if (!mov) {
+ updateGlobalMessageQueue(messageQueueId, _id);
+
+ return;
+ }
+
+
+ if (_movement || !_statics)
+ return;
+
+ Common::Point point;
+
+ _statics->getSomeXY(point);
+
+ int newx = _ox - point.x;
+ int newy = _oy - point.y;
+
+ _movement = mov;
+
+ if (_flags & 0x40)
+ _movement->gotoLastFrame();
+ else
+ _movement->gotoFirstFrame();
+
+ _stepArray.clear();
+ _stepArray.insertPoints(points, pointsCount);
+
+ if (!(_flags & 0x40)) {
+ if (!_movement->_currDynamicPhaseIndex) {
+ _stepArray.getCurrPoint(&point);
+ newx += point.x + _movement->_mx;
+ newy += point.y + _movement->_my;
+ _stepArray.gotoNextPoint();
+
+ ExCommand *ex = _movement->_currDynamicPhase->getExCommand();
+
+ if (ex) {
+ if (ex->_messageKind == 35) {
+ ExCommand *newEx = ex->createClone();
+
+ newEx->_excFlags |= 2u;
+ newEx->sendMessage();
+ }
+ }
+ }
+ }
+
+ _movement->getCurrDynamicPhaseXY(point);
+ setOXY(point.x + newx, point.y + newy);
+
+ if ((_movement->_staticsObj2->_staticsId >> 8) & 0x40)
+ _flags |= 8;
+ else
+ _flags &= 0xFFF7;
+
+ _flags |= 1;
+ _messageQueueId = messageQueueId;
+ _movement->_currDynamicPhase->_countdown = _movement->_currDynamicPhase->_initialCountdown;
+ _movement->_counter = 0;
+ _counter = _initialCounter;
+ _someDynamicPhaseIndex = someDynamicPhaseIndex;
+
+ ExCommand *ex = new ExCommand(_id, 17, 23, 0, 0, movementId, 1, 0, 0, 0);
+
+ ex->_keyCode = _okeyCode;
+ ex->_excFlags = 2;
+ ex->postMessage();
}
bool StaticANIObject::startAnimEx(int movid, int parId, int flag1, int flag2) {
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
index 8328e7679b..89703965cd 100644
--- a/engines/fullpipe/statics.h
+++ b/engines/fullpipe/statics.h
@@ -47,6 +47,7 @@ class StepArray : public CObject {
Common::Point *getCurrPoint(Common::Point *point);
Common::Point *getPoint(Common::Point *point, int index, int offset);
bool gotoNextPoint();
+ void insertPoints(Common::Point **points, int pointsCount);
};
class StaticPhase : public Picture {
diff --git a/engines/neverhood/modules/module2200.cpp b/engines/neverhood/modules/module2200.cpp
index f9033a9dbe..6618cb3ab0 100644
--- a/engines/neverhood/modules/module2200.cpp
+++ b/engines/neverhood/modules/module2200.cpp
@@ -885,7 +885,7 @@ void Scene2205::update() {
} else if (_isLightOn && !getGlobalVar(V_LIGHTS_ON)) {
_palette->addPalette(0xD00A028D, 0, 256, 0);
changeBackground(0xD00A028D);
- _ssLightSwitch->setFileHashes(0x2D339030, 0xDAC86E84);
+ _ssLightSwitch->setFileHashes(0xD6C86E84, 0xDAC86E84);
sendMessage(_ssDoorFrame, 0x2000, 0);
changeMouseCursor(0xA0289D08);
_isKlaymenInLight = true;
diff --git a/engines/neverhood/modules/module2300.cpp b/engines/neverhood/modules/module2300.cpp
index c0edc95873..68ae07f2bb 100644
--- a/engines/neverhood/modules/module2300.cpp
+++ b/engines/neverhood/modules/module2300.cpp
@@ -31,14 +31,14 @@ static const uint32 kModule2300SoundList[] = {
};
Module2300::Module2300(NeverhoodEngine *vm, Module *parentModule, int which)
- : Module(vm, parentModule), _soundVolume(0) {
+ : Module(vm, parentModule), _waterfallSoundVolume(0) {
_vm->_soundMan->addSoundList(0x1A214010, kModule2300SoundList);
_vm->_soundMan->setSoundListParams(kModule2300SoundList, true, 50, 600, 10, 150);
- _isWallBroken = getGlobalVar(V_WALL_BROKEN) != 0;
+ _isWaterfallRunning = getGlobalVar(V_WALL_BROKEN) != 1;
- if (_isWallBroken) {
+ if (_isWaterfallRunning) {
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 0);
_vm->_soundMan->playSoundLooping(0x90F0D1C3);
} else {
@@ -78,8 +78,8 @@ void Module2300::createScene(int sceneNum, int which) {
case 1:
_vm->gameState().sceneNum = 1;
createNavigationScene(0x004B67E8, which);
- if (_isWallBroken) {
- _soundVolume = 15;
+ if (_isWaterfallRunning) {
+ _waterfallSoundVolume = 15;
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 15);
}
break;
@@ -92,10 +92,10 @@ void Module2300::createScene(int sceneNum, int which) {
if (getGlobalVar(V_WALL_BROKEN))
createNavigationScene(0x004B68F0, which);
else {
- _vm->_soundMan->setSoundVolume(0x90F0D1C3, _soundVolume);
+ _vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
createNavigationScene(0x004B68A8, which);
- if (_isWallBroken) {
- _soundVolume = 87;
+ if (_isWaterfallRunning) {
+ _waterfallSoundVolume = 87;
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 87);
}
}
@@ -161,10 +161,10 @@ void Module2300::updateScene() {
} else {
switch (_sceneNum) {
case 1:
- if (_isWallBroken && navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 4 &&
+ if (_isWaterfallRunning && navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 4 &&
navigationScene()->getFrameNumber() % 2) {
- _soundVolume++;
- _vm->_soundMan->setSoundVolume(0x90F0D1C3, _soundVolume);
+ _waterfallSoundVolume++;
+ _vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
}
if (navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 0 &&
navigationScene()->getFrameNumber() == 50) {
@@ -174,9 +174,9 @@ void Module2300::updateScene() {
}
break;
case 3:
- if (_isWallBroken && navigationScene()->isWalkingForward() && navigationScene()->getFrameNumber() % 2) {
- _soundVolume--;
- _vm->_soundMan->setSoundVolume(0x90F0D1C3, _soundVolume);
+ if (_isWaterfallRunning && navigationScene()->isWalkingForward() && navigationScene()->getFrameNumber() % 2) {
+ _waterfallSoundVolume--;
+ _vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
}
break;
}
diff --git a/engines/neverhood/modules/module2300.h b/engines/neverhood/modules/module2300.h
index 57235986d9..58bffb710c 100644
--- a/engines/neverhood/modules/module2300.h
+++ b/engines/neverhood/modules/module2300.h
@@ -37,8 +37,8 @@ public:
virtual ~Module2300();
protected:
int _sceneNum;
- bool _isWallBroken;
- int _soundVolume;
+ int _waterfallSoundVolume;
+ bool _isWaterfallRunning;
void createScene(int sceneNum, int which);
void updateScene();
};
diff --git a/engines/neverhood/modules/module3000.cpp b/engines/neverhood/modules/module3000.cpp
index 59b2df260e..d4809611ad 100644
--- a/engines/neverhood/modules/module3000.cpp
+++ b/engines/neverhood/modules/module3000.cpp
@@ -39,7 +39,7 @@ static const uint32 kModule3000SoundList[] = {
};
Module3000::Module3000(NeverhoodEngine *vm, Module *parentModule, int which)
- : Module(vm, parentModule), _soundVolume(0) {
+ : Module(vm, parentModule), _waterfallSoundVolume(0) {
_vm->_soundMan->addSoundList(0x81293110, kModule3000SoundList);
_vm->_soundMan->setSoundListParams(kModule3000SoundList, true, 50, 600, 5, 150);
@@ -48,9 +48,9 @@ Module3000::Module3000(NeverhoodEngine *vm, Module *parentModule, int which)
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
_vm->_soundMan->playTwoSounds(0x81293110, 0x41861371, 0x43A2507F, 0);
- _isWallBroken = getGlobalVar(V_WALL_BROKEN) != 0;
+ _isWaterfallRunning = getGlobalVar(V_WALL_BROKEN) != 1;
- if (!_isWallBroken) {
+ if (_isWaterfallRunning) {
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 0);
_vm->_soundMan->playSoundLooping(0x90F0D1C3);
}
@@ -78,12 +78,11 @@ void Module3000::createScene(int sceneNum, int which) {
static const byte kNavigationTypes06[] = {5};
debug(1, "Module3000::createScene(%d, %d)", sceneNum, which);
_vm->gameState().sceneNum = sceneNum;
- _isWallBroken = getGlobalVar(V_WALL_BROKEN) != 0;
switch (_vm->gameState().sceneNum) {
case 1:
if (!getGlobalVar(V_BOLT_DOOR_OPEN)) {
createNavigationScene(0x004B7C80, which);
- } else if (_isWallBroken) {
+ } else if (getGlobalVar(V_WALL_BROKEN)) {
createNavigationScene(0x004B7CE0, which);
} else {
createNavigationScene(0x004B7CB0, which);
@@ -91,11 +90,11 @@ void Module3000::createScene(int sceneNum, int which) {
break;
case 2:
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
- if (!_isWallBroken) {
- _soundVolume = 90;
+ if (_isWaterfallRunning) {
+ _waterfallSoundVolume = 90;
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 90);
}
- if (_isWallBroken) {
+ if (getGlobalVar(V_WALL_BROKEN)) {
createNavigationScene(0x004B7D58, which);
} else {
createNavigationScene(0x004B7D10, which);
@@ -104,7 +103,7 @@ void Module3000::createScene(int sceneNum, int which) {
case 3:
if (getGlobalVar(V_STAIRS_DOWN))
createNavigationScene(0x004B7E60, which);
- else if (_isWallBroken)
+ else if (getGlobalVar(V_WALL_BROKEN))
createNavigationScene(0x004B7DA0, which);
else
createNavigationScene(0x004B7E00, which);
@@ -152,12 +151,12 @@ void Module3000::createScene(int sceneNum, int which) {
// NOTE: Newly introduced sceneNums
case 1001:
if (!getGlobalVar(V_BOLT_DOOR_OPEN))
- if (_isWallBroken)
+ if (getGlobalVar(V_WALL_BROKEN))
createSmackerScene(0x00940021, true, true, false);
else
createSmackerScene(0x01140021, true, true, false);
else
- if (_isWallBroken)
+ if (getGlobalVar(V_WALL_BROKEN))
createSmackerScene(0x001011B1, true, true, false);
else
createSmackerScene(0x001021B1, true, true, false);
@@ -195,8 +194,8 @@ void Module3000::updateScene() {
break;
case 2:
_vm->_soundMan->playTwoSounds(0x81293110, 0x41861371, 0x43A2507F, 0);
- if (_isWallBroken) {
- _soundVolume = 0;
+ if (_isWaterfallRunning) {
+ _waterfallSoundVolume = 0;
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 0);
}
if (_moduleResult == 0) {
@@ -240,7 +239,7 @@ void Module3000::updateScene() {
createScene(8, -1);
break;
case 8:
- _isWallBroken = getGlobalVar(V_WALL_BROKEN) != 0;
+ _isWaterfallRunning = getGlobalVar(V_WALL_BROKEN) != 1;
if (_moduleResult != 1) {
_vm->_soundMan->setSoundListParams(kModule3000SoundList, true, 0, 0, 0, 0);
createScene(4, 1);
@@ -301,12 +300,12 @@ void Module3000::updateScene() {
} else if (frameNumber == 10) {
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
}
- if (!_isWallBroken && _soundVolume < 90 && frameNumber % 2) {
+ if (_isWaterfallRunning && _waterfallSoundVolume < 90 && frameNumber % 2) {
if (frameNumber == 0)
- _soundVolume = 40;
+ _waterfallSoundVolume = 40;
else
- _soundVolume++;
- _vm->_soundMan->setSoundVolume(0x90F0D1C3, _soundVolume);
+ _waterfallSoundVolume++;
+ _vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
}
}
}
@@ -315,9 +314,9 @@ void Module3000::updateScene() {
if (navigationScene()->isWalkingForward()) {
uint32 frameNumber = navigationScene()->getFrameNumber();
int navigationIndex = navigationScene()->getNavigationIndex();
- if (!_isWallBroken && _soundVolume > 1 && frameNumber % 2) {
- _soundVolume--;
- _vm->_soundMan->setSoundVolume(0x90F0D1C3, _soundVolume);
+ if (_isWaterfallRunning && _waterfallSoundVolume > 1 && frameNumber % 2) {
+ _waterfallSoundVolume--;
+ _vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
}
if (navigationIndex == 0) {
if (frameNumber == 35) {
@@ -340,12 +339,12 @@ void Module3000::updateScene() {
if (frameNumber == 40) {
_vm->_soundMan->playTwoSounds(0x81293110, 0x40030A51, 0xC862CA15, 0);
}
- if (!_isWallBroken && _soundVolume < 90 && frameNumber % 2) {
+ if (_isWaterfallRunning && _waterfallSoundVolume < 90 && frameNumber % 2) {
if (frameNumber == 0)
- _soundVolume = 40;
+ _waterfallSoundVolume = 40;
else
- _soundVolume++;
- _vm->_soundMan->setSoundVolume(0x90F0D1C3, _soundVolume);
+ _waterfallSoundVolume++;
+ _vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
}
}
}
diff --git a/engines/neverhood/modules/module3000.h b/engines/neverhood/modules/module3000.h
index e5c251f828..3d895b8d8a 100644
--- a/engines/neverhood/modules/module3000.h
+++ b/engines/neverhood/modules/module3000.h
@@ -34,8 +34,8 @@ public:
Module3000(NeverhoodEngine *vm, Module *parentModule, int which);
virtual ~Module3000();
protected:
- int _soundVolume;
- bool _isWallBroken;
+ int _waterfallSoundVolume;
+ bool _isWaterfallRunning;
void createScene(int sceneNum, int which);
void updateScene();
};
diff --git a/engines/pegasus/items/item.cpp b/engines/pegasus/items/item.cpp
index 8089f2b93d..830d3f2f34 100644
--- a/engines/pegasus/items/item.cpp
+++ b/engines/pegasus/items/item.cpp
@@ -39,9 +39,9 @@
namespace Pegasus {
Item::Item(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) : IDObject(id) {
- _itemNeighborhood = neighborhood;
- _itemRoom = room;
- _itemDirection = direction;
+ _originalNeighborhood = _itemNeighborhood = neighborhood;
+ _originalRoom = _itemRoom = room;
+ _originalDirection = _itemDirection = direction;
_itemWeight = 1;
_itemOwnerID = kNoActorID;
_itemState = 0;
@@ -131,6 +131,14 @@ Item::~Item() {
delete[] _itemExtras.entries;
}
+void Item::reset() {
+ _itemNeighborhood = _originalNeighborhood;
+ _itemRoom = _originalRoom;
+ _itemDirection = _originalDirection;
+ _itemOwnerID = kNoActorID;
+ _itemState = 0;
+}
+
void Item::writeToStream(Common::WriteStream *stream) {
stream->writeUint16BE(_itemNeighborhood);
stream->writeUint16BE(_itemRoom);
diff --git a/engines/pegasus/items/item.h b/engines/pegasus/items/item.h
index a1451b2a58..26cccf043c 100644
--- a/engines/pegasus/items/item.h
+++ b/engines/pegasus/items/item.h
@@ -339,6 +339,9 @@ public:
void findItemExtra(const uint32 extraID, ItemExtraEntry &entry);
+ // Reset to its original state at the beginning of the game
+ void reset();
+
protected:
NeighborhoodID _itemNeighborhood;
RoomID _itemRoom;
@@ -347,6 +350,10 @@ protected:
WeightType _itemWeight;
ItemState _itemState;
+ NeighborhoodID _originalNeighborhood;
+ RoomID _originalRoom;
+ DirectionConstant _originalDirection;
+
JMPItemInfo _itemInfo;
ItemStateInfo _sharedAreaInfo;
ItemExtraInfo _itemExtras;
diff --git a/engines/pegasus/items/itemlist.cpp b/engines/pegasus/items/itemlist.cpp
index ff8cae546b..4b58d9ad78 100644
--- a/engines/pegasus/items/itemlist.cpp
+++ b/engines/pegasus/items/itemlist.cpp
@@ -64,4 +64,9 @@ Item *ItemList::findItemByID(const ItemID id) {
return 0;
}
+void ItemList::resetAllItems() {
+ for (ItemIterator it = begin(); it != end(); it++)
+ (*it)->reset();
+}
+
} // End of namespace Pegasus
diff --git a/engines/pegasus/items/itemlist.h b/engines/pegasus/items/itemlist.h
index 9b59206ab3..22bef2c96e 100644
--- a/engines/pegasus/items/itemlist.h
+++ b/engines/pegasus/items/itemlist.h
@@ -48,6 +48,7 @@ public:
virtual void readFromStream(Common::ReadStream *stream);
Item *findItemByID(const ItemID id);
+ void resetAllItems();
};
typedef ItemList::iterator ItemIterator;
diff --git a/engines/pegasus/neighborhood/caldoria/caldoria.cpp b/engines/pegasus/neighborhood/caldoria/caldoria.cpp
index 0707a83e87..7977c17f12 100644
--- a/engines/pegasus/neighborhood/caldoria/caldoria.cpp
+++ b/engines/pegasus/neighborhood/caldoria/caldoria.cpp
@@ -1916,10 +1916,13 @@ uint Caldoria::getNumHints() {
numHints = 1;
}
break;
+#if 0
+ // The hint file is missing
case MakeRoomView(kCaldoria49, kEast):
case MakeRoomView(kCaldoria54, kEast):
numHints = 1;
break;
+#endif
case MakeRoomView(kCaldoria49, kNorth):
numHints = 1;
break;
@@ -1950,9 +1953,12 @@ Common::String Caldoria::getHintMovie(uint hintNum) {
}
return "Images/AI/Globals/XGLOB1A";
+#if 0
+ // The hint file is missing
case MakeRoomView(kCaldoria49, kEast):
case MakeRoomView(kCaldoria54, kEast):
return "Images/AI/Caldoria/X49E";
+#endif
case MakeRoomView(kCaldoria49, kNorth):
return "Images/AI/Caldoria/X49NB2";
}
diff --git a/engines/pegasus/neighborhood/mars/mars.cpp b/engines/pegasus/neighborhood/mars/mars.cpp
index 435bcd4c9e..a83b7802f5 100644
--- a/engines/pegasus/neighborhood/mars/mars.cpp
+++ b/engines/pegasus/neighborhood/mars/mars.cpp
@@ -535,6 +535,10 @@ void Mars::doorOpened() {
}
void Mars::setUpReactorEnergyDrain() {
+ // If there's no energy monitor, there's nothing to do
+ if (!g_energyMonitor)
+ return;
+
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars51, kEast):
if (GameState.isCurrentDoorOpen()) {
diff --git a/engines/pegasus/neighborhood/tsa/fulltsa.cpp b/engines/pegasus/neighborhood/tsa/fulltsa.cpp
index 75f652ad56..c0fa3c4fe6 100644
--- a/engines/pegasus/neighborhood/tsa/fulltsa.cpp
+++ b/engines/pegasus/neighborhood/tsa/fulltsa.cpp
@@ -2643,6 +2643,7 @@ void FullTSA::receiveNotification(Notification *notification, const Notification
GameState.setMarsReadyForShuttleTransport(false);
GameState.setMarsFinishedCanyonChase(false);
GameState.setMarsThreadedMaze(false);
+ GameState.setMarsSawRobotLeave(false);
break;
case kPlayerOnWayToWSC:
_vm->jumpToNewEnvironment(kWSCID, kWSC01, kWest);
diff --git a/engines/pegasus/neighborhood/tsa/tinytsa.cpp b/engines/pegasus/neighborhood/tsa/tinytsa.cpp
index 0326c7f2ee..c808325b0f 100644
--- a/engines/pegasus/neighborhood/tsa/tinytsa.cpp
+++ b/engines/pegasus/neighborhood/tsa/tinytsa.cpp
@@ -327,6 +327,7 @@ void TinyTSA::receiveNotification(Notification *notification, const Notification
GameState.setMarsReadyForShuttleTransport(false);
GameState.setMarsFinishedCanyonChase(false);
GameState.setMarsThreadedMaze(false);
+ GameState.setMarsSawRobotLeave(false);
break;
case kPlayerOnWayToWSC:
_vm->jumpToNewEnvironment(kWSCID, kWSC01, kWest);
diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp
index c5edd34a01..2062fe6847 100644
--- a/engines/pegasus/pegasus.cpp
+++ b/engines/pegasus/pegasus.cpp
@@ -36,6 +36,7 @@
#include "backends/keymapper/keymapper.h"
#include "base/plugins.h"
#include "base/version.h"
+#include "gui/message.h"
#include "gui/saveload.h"
#include "video/theora_decoder.h"
#include "video/qt_decoder.h"
@@ -379,20 +380,21 @@ Common::Error PegasusEngine::showSaveDialog() {
int slot = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
- Common::Error result;
+ if (slot >= 0)
+ return saveGameState(slot, slc.getResultString());
- if (slot >= 0) {
- if (saveGameState(slot, slc.getResultString()).getCode() == Common::kNoError)
- result = Common::kNoError;
- else
- result = Common::kUnknownError;
- } else {
- result = Common::kUserCanceled;
- }
+ return Common::kUserCanceled;
+}
- return result;
+void PegasusEngine::showSaveFailedDialog(const Common::Error &status) {
+ Common::String failMessage = Common::String::format(_("Gamestate save failed (%s)! "
+ "Please consult the README for basic information, and for "
+ "instructions on how to obtain further assistance."), status.getDesc().c_str());
+ GUI::MessageDialog dialog(failMessage);
+ dialog.runModal();
}
+
GUI::Debugger *PegasusEngine::getDebugger() {
return _console;
}
@@ -969,8 +971,14 @@ void PegasusEngine::doGameMenuCommand(const GameMenuCommand command) {
resetIntroTimer();
break;
case kMenuCmdPauseSave:
- if (showSaveDialog().getCode() != Common::kUserCanceled)
+ result = showSaveDialog();
+
+ if (result.getCode() != Common::kUserCanceled) {
+ if (result.getCode() != Common::kNoError)
+ showSaveFailedDialog(result);
+
pauseMenu(false);
+ }
break;
case kMenuCmdPauseContinue:
pauseMenu(false);
@@ -1021,7 +1029,12 @@ void PegasusEngine::handleInput(const Input &input, const Hotspot *cursorSpot) {
// Can only save during a game and not in the demo
if (g_neighborhood && !isDemo()) {
pauseEngine(true);
- showSaveDialog();
+
+ Common::Error result = showSaveDialog();
+
+ if (result.getCode() != Common::kNoError && result.getCode() != Common::kUserCanceled)
+ showSaveFailedDialog(result);
+
pauseEngine(false);
}
}
@@ -1669,6 +1682,9 @@ void PegasusEngine::startNewGame() {
removeAllItemsFromInventory();
removeAllItemsFromBiochips();
+ // Properly reset all items to their original state
+ g_allItems.resetAllItems();
+
BiochipItem *biochip = (BiochipItem *)_allItems.findItemByID(kAIBiochip);
addItemToBiochips(biochip);
diff --git a/engines/pegasus/pegasus.h b/engines/pegasus/pegasus.h
index fb66eb7586..d88545a4d1 100644
--- a/engines/pegasus/pegasus.h
+++ b/engines/pegasus/pegasus.h
@@ -257,6 +257,7 @@ private:
bool _saveAllowed, _loadAllowed; // It's so nice that this was in the original code already :P
Common::Error showLoadDialog();
Common::Error showSaveDialog();
+ void showSaveFailedDialog(const Common::Error &status);
bool _saveRequested, _loadRequested;
// Misc.
diff --git a/engines/wintermute/base/font/base_font_truetype.cpp b/engines/wintermute/base/font/base_font_truetype.cpp
index c5a1e91ef5..df9a8648db 100644
--- a/engines/wintermute/base/font/base_font_truetype.cpp
+++ b/engines/wintermute/base/font/base_font_truetype.cpp
@@ -625,6 +625,8 @@ bool BaseFontTT::initFont() {
warning("Looking for %s", fontName.c_str());
_font = FontMan.getFontByName(fontName);
}
+#else
+ warning("BaseFontTT::InitFont - FreeType2-support not compiled in, TTF-fonts will not be loaded");
#endif // USE_FREETYPE2
// Fallback4: Just use the Big GUI-font. (REALLY undesireable)
diff --git a/engines/wintermute/video/video_theora_player.cpp b/engines/wintermute/video/video_theora_player.cpp
index b0c469c440..e1553580ec 100644
--- a/engines/wintermute/video/video_theora_player.cpp
+++ b/engines/wintermute/video/video_theora_player.cpp
@@ -127,6 +127,7 @@ bool VideoTheoraPlayer::initialize(const Common::String &filename, const Common:
#if defined (USE_THEORADEC)
_theoraDecoder = new Video::TheoraDecoder();
#else
+ warning("VideoTheoraPlayer::initialize - Theora support not compiled in, video will be skipped: %s", filename.c_str());
return STATUS_FAILED;
#endif
_theoraDecoder->loadStream(_file);