diff options
Diffstat (limited to 'engines')
91 files changed, 2567 insertions, 507 deletions
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 e855c71fcf..c8f5599687 100644 --- a/engines/avalanche/avalot.cpp +++ b/engines/avalanche/avalot.cpp @@ -202,6 +202,8 @@ void AvalancheEngine::setup() { _graphics->drawSoundLight(_sound->_soundFl); + drawToolbar(); + int16 loadSlot = ConfMan.instance().getInt("save_slot"); if (loadSlot >= 0) { _thinks = 2; // You always have money. @@ -218,8 +220,6 @@ void AvalancheEngine::setup() { newGame(); - drawToolbar(); - thinkAbout(kObjectMoney, kThing); _dialogs->displayScrollChain('Q', 83); // Info on the game, etc. @@ -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 dc1c277877..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(); @@ -363,6 +361,7 @@ void Dialogs::scrollModeMusic() { value = 11; break; default: + error("cannot happen"); break; } @@ -392,7 +391,7 @@ void Dialogs::scrollModeMusic() { _vm->_graphics->restoreScreen(); _vm->_graphics->removeBackup(); - _vm->_seeScroll = false; + _vm->_animationsEnabled = true; CursorMan.showMouse(true); } @@ -645,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..5f47aeb894 --- /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 ((firstSmaller < 12) && (_data[firstSmaller]._score >= _vm->_score)) + 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 7db0d14890..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 ""; @@ -2021,8 +2021,7 @@ void Parser::doThat() { break; case 55: if (_vm->_room == kRoomArgentPub) - // play_nim(); - warning("STUB: Parser::doThat() - case kVerbCodeplay - play_nim()"); + _vm->_nim->playNim(); else _vm->_dialogs->displayText(kWhat); break; @@ -2307,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/avalanche/shootemup.cpp b/engines/avalanche/shootemup.cpp index 8d61316daa..cabd19d6f9 100644 --- a/engines/avalanche/shootemup.cpp +++ b/engines/avalanche/shootemup.cpp @@ -95,7 +95,7 @@ ShootEmUp::ShootEmUp(AvalancheEngine *vm) { _gotOut = false; } -void ShootEmUp::run() { +uint16 ShootEmUp::run() { CursorMan.showMouse(false); _vm->_graphics->saveScreen(); _vm->fadeOut(); @@ -142,12 +142,14 @@ void ShootEmUp::run() { if (delay <= 55) _vm->_system->delayMillis(55 - delay); // Replaces slowdown(); 55 comes from 18.2 Hz (B Flight). }; - + _vm->fadeOut(); _vm->_graphics->restoreScreen(); _vm->_graphics->removeBackup(); _vm->fadeIn(); CursorMan.showMouse(true); + + return _score; } bool ShootEmUp::overlap(uint16 a1x, uint16 a1y, uint16 a2x, uint16 a2y, uint16 b1x, uint16 b1y, uint16 b2x, uint16 b2y) { diff --git a/engines/avalanche/shootemup.h b/engines/avalanche/shootemup.h index 4c010aa71e..3cdcc1d5cd 100644 --- a/engines/avalanche/shootemup.h +++ b/engines/avalanche/shootemup.h @@ -35,7 +35,7 @@ class ShootEmUp { public: ShootEmUp(AvalancheEngine *vm); - void run(); + uint16 run(); private: struct Sprite { diff --git a/engines/avalanche/timer.cpp b/engines/avalanche/timer.cpp index 7b6e1ee1ce..a9753b3cce 100644 --- a/engines/avalanche/timer.cpp +++ b/engines/avalanche/timer.cpp @@ -333,12 +333,11 @@ void Timer::hangAround2() { // We don't need the ShootEmUp during the whole game, it's only playable once. ShootEmUp *shootemup = new ShootEmUp(_vm); - shootemup->run(); + _shootEmUpScore = shootemup->run(); delete shootemup; } void Timer::afterTheShootemup() { - // Only placed this here to replace the minigame. TODO: Remove it when the shoot em' up is implemented! _vm->flipRoom(_vm->_room, 1); _vm->_animation->_sprites[0]->init(0, true); // Avalot. @@ -347,27 +346,15 @@ void Timer::afterTheShootemup() { _vm->_objects[kObjectCrossbow - 1] = true; _vm->refreshObjectList(); - // Same as the added line above: TODO: Remove it later!!! - _vm->_dialogs->displayText(Common::String("P.S.: There should have been the mini-game called \"shoot em' up\", " \ - "but I haven't implemented it yet: you get the crossbow automatically.") + kControlNewLine + kControlNewLine + "Peter (uruk)"); - -#if 0 - byte shootscore, gain; - - shootscore = mem[storage_seg * storage_ofs]; - gain = (shootscore + 5) / 10; // Rounding up. - - display(string("\6Your score was ") + strf(shootscore) + '.' + "\r\rYou gain (" + - strf(shootscore) + " 0xF6 10) = " + strf(gain) + " points."); + byte gain = (_shootEmUpScore + 5) / 10; // Rounding up. + _vm->_dialogs->displayText(Common::String::format("%cYour score was %d.%c%cYou gain (%d \xf6 10) = %d points.", kControlItalic, _shootEmUpScore, kControlNewLine, kControlNewLine, _shootEmUpScore, gain)); if (gain > 20) { - display("But we won't let you have more than 20 points!"); - points(20); + _vm->_dialogs->displayText("But we won't let you have more than 20 points!"); + _vm->incScore(20); } else - points(gain); -#endif + _vm->incScore(gain); - warning("STUB: Timer::after_the_shootemup()"); _vm->_dialogs->displayScrollChain('Q', 70); } @@ -712,6 +699,8 @@ void Timer::resetVariables() { _times[i]._action = 0; _times[i]._reason = 0; } + + _shootEmUpScore = 0; } } // End of namespace Avalanche. diff --git a/engines/avalanche/timer.h b/engines/avalanche/timer.h index fd51544fd1..ad6ac0eae6 100644 --- a/engines/avalanche/timer.h +++ b/engines/avalanche/timer.h @@ -170,7 +170,7 @@ public: private: AvalancheEngine *_vm; - + byte _shootEmUpScore; }; } // End of namespace Avalanche. diff --git a/engines/cruise/font.cpp b/engines/cruise/font.cpp index c63be30f77..80fb0e8a02 100644 --- a/engines/cruise/font.cpp +++ b/engines/cruise/font.cpp @@ -148,8 +148,6 @@ void initSystem() { preloadData[i].nofree = 0; } - lowMemory = 0; - doFade = 0; fadeFlag = 0; scroll = 0; diff --git a/engines/cruise/function.cpp b/engines/cruise/function.cpp index e727ac73cb..7af6b73238 100644 --- a/engines/cruise/function.cpp +++ b/engines/cruise/function.cpp @@ -606,7 +606,7 @@ int16 Op_InitializeState() { } int16 Op_GetlowMemory() { - return lowMemory; + return 0; } int16 Op_AniDir() { diff --git a/engines/cruise/saveload.cpp b/engines/cruise/saveload.cpp index a991c29583..a734db4b3b 100644 --- a/engines/cruise/saveload.cpp +++ b/engines/cruise/saveload.cpp @@ -182,11 +182,13 @@ static void syncFilesDatabase(Common::Serializer &s) { s.syncAsUint16LE(fe.resType); s.syncAsUint16LE(fe.height); - // TODO: Have a look at the saving/loading of this pointer + // Remember whether this file database was open or not. + // Upon loading, loadSavegameData uses this information + // in order to re-open the file databases accordingly. tmp = (fe.subData.ptr) ? 1 : 0; s.syncAsUint32LE(tmp); if (s.isLoading()) { - fe.subData.ptr = (uint8 *)tmp; + fe.subData.ptr = tmp ? (uint8 *)1 : 0; } s.syncAsSint16LE(fe.subData.index); @@ -195,11 +197,11 @@ static void syncFilesDatabase(Common::Serializer &s) { s.syncAsSint16LE(fe.subData.transparency); - // TODO: Have a look at the saving/loading of this pointer + // Treat fe.subData.ptrMask the same as fe.subData.ptr. tmp = (fe.subData.ptrMask) ? 1 : 0; s.syncAsUint32LE(tmp); if (s.isLoading()) { - fe.subData.ptrMask = (uint8 *)tmp; + fe.subData.ptrMask = tmp ? (uint8 *)1 : 0; } s.syncAsUint16LE(fe.subData.resourceType); @@ -806,7 +808,6 @@ Common::Error saveSavegameData(int saveGameIdx, const Common::String &saveName) } Common::Error loadSavegameData(int saveGameIdx) { - int lowMemorySave; Common::String saveName; cellStruct *currentcellHead; @@ -878,20 +879,19 @@ Common::Error loadSavegameData(int saveGameIdx) { lastAni[0] = 0; - lowMemorySave = lowMemory; - for (int i = 0; i < NUM_FILE_ENTRIES; i++) { if (filesDatabase[i].subData.ptr) { int j; int k; - for (j = i + 1; j < NUM_FILE_ENTRIES && filesDatabase[j].subData.ptr && !strcmp(filesDatabase[i].subData.name, filesDatabase[j].subData.name) && (filesDatabase[j].subData.index == (j - i)); j++) + for (j = i + 1; j < NUM_FILE_ENTRIES && + filesDatabase[j].subData.ptr && + !strcmp(filesDatabase[i].subData.name, filesDatabase[j].subData.name) && + (filesDatabase[j].subData.index == (j - i)); + j++) ; for (k = i; k < j; k++) { - if (filesDatabase[k].subData.ptrMask) - lowMemory = 0; - filesDatabase[k].subData.ptr = NULL; filesDatabase[k].subData.ptrMask = NULL; } @@ -908,7 +908,6 @@ Common::Error loadSavegameData(int saveGameIdx) { } i = j - 1; - lowMemory = lowMemorySave; } } diff --git a/engines/cruise/vars.cpp b/engines/cruise/vars.cpp index f7c74c8e6d..9a59c8a714 100644 --- a/engines/cruise/vars.cpp +++ b/engines/cruise/vars.cpp @@ -31,7 +31,6 @@ uint8 selectColor = 3; uint8 titleColor = 2; uint8 subColor = 5; -int16 lowMemory; int16 scroll; int16 switchPal; char cmdLine[90]; diff --git a/engines/cruise/vars.h b/engines/cruise/vars.h index 8bfcdc57d4..fe3f7d6303 100644 --- a/engines/cruise/vars.h +++ b/engines/cruise/vars.h @@ -59,7 +59,6 @@ extern uint8 selectColor; extern uint8 titleColor; extern uint8 subColor; -extern int16 lowMemory; extern int16 scroll; extern int16 switchPal; extern char cmdLine[90]; diff --git a/engines/fullpipe/behavior.cpp b/engines/fullpipe/behavior.cpp index 2e3a4e2e44..14e9c33bdf 100644 --- a/engines/fullpipe/behavior.cpp +++ b/engines/fullpipe/behavior.cpp @@ -83,7 +83,7 @@ void BehaviorManager::updateBehaviors() { if (!_isActive) return; - debug(0, "BehaviorManager::updateBehaviors()"); + debug(4, "BehaviorManager::updateBehaviors()"); for (uint i = 0; i < _behaviors.size(); i++) { BehaviorInfo *beh = _behaviors[i]; @@ -122,7 +122,7 @@ void BehaviorManager::updateBehaviors() { } void BehaviorManager::updateBehavior(BehaviorInfo *behaviorInfo, BehaviorEntry *entry) { - debug(0, "BehaviorManager::updateBehavior() %d", entry->_itemsCount); + debug(4, "BehaviorManager::updateBehavior() %d", entry->_itemsCount); for (int i = 0; i < entry->_itemsCount; i++) { BehaviorEntryInfo *bhi = entry->_items[i]; if (!(bhi->_flags & 1)) { @@ -144,7 +144,7 @@ void BehaviorManager::updateBehavior(BehaviorInfo *behaviorInfo, BehaviorEntry * } void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, int delay, BehaviorEntry *bhe) { - debug(0, "BehaviorManager::updateStaticAniBehavior(%s)", transCyrillic((byte *)ani->_objectName)); + debug(4, "BehaviorManager::updateStaticAniBehavior(%s)", transCyrillic((byte *)ani->_objectName)); MessageQueue *mq = 0; @@ -236,7 +236,7 @@ void BehaviorInfo::clear() { } void BehaviorInfo::initAmbientBehavior(GameVar *var, Scene *sc) { - debug(0, "BehaviorInfo::initAmbientBehavior(%s)", transCyrillic((byte *)var->_varName)); + debug(4, "BehaviorInfo::initAmbientBehavior(%s)", transCyrillic((byte *)var->_varName)); clear(); _itemsCount = 1; @@ -260,7 +260,7 @@ void BehaviorInfo::initAmbientBehavior(GameVar *var, Scene *sc) { } void BehaviorInfo::initObjectBehavior(GameVar *var, Scene *sc, StaticANIObject *ani) { - debug(0, "BehaviorInfo::initObjectBehavior(%s)", transCyrillic((byte *)var->_varName)); + debug(4, "BehaviorInfo::initObjectBehavior(%s)", transCyrillic((byte *)var->_varName)); clear(); diff --git a/engines/fullpipe/constants.h b/engines/fullpipe/constants.h index e670645431..8f3f587714 100644 --- a/engines/fullpipe/constants.h +++ b/engines/fullpipe/constants.h @@ -266,6 +266,27 @@ namespace Fullpipe { #define TrubaLeft 474 #define TrubaUp 680 +// Main Menu +#define PIC_MNU_AUTHORS_L 4624 +#define PIC_MNU_CONTINUE_L 4626 +#define PIC_MNU_DEBUG_L 4632 +#define PIC_MNU_EXIT_L 4622 +#define PIC_MNU_LOAD_L 4628 +#define PIC_MNU_MUSICSLIDER_D 4914 +#define PIC_MNU_MUSICSLIDER_L 4915 +#define PIC_MNU_RESTART_L 5299 +#define PIC_MNU_SAVE_L 4630 +#define PIC_MNU_SLIDER_D 4913 +#define PIC_MNU_SLIDER_L 4912 + +// Query dialog +#define PIC_MEX_BGR 5300 +#define PIC_MEX_CANCEL 5302 +#define PIC_MEX_OK 5301 +#define PIC_MOV_BGR 5343 +#define PIC_MOV_CANCEL 5345 +#define PIC_MOV_OK 5344 + // Intro #define ANI_IN1MAN 5110 #define MSG_INTR_ENDINTRO 5139 @@ -1295,25 +1316,41 @@ namespace Fullpipe { #define MSG_SC29_STOPRIDE 2107 #define MV_ASS_HITGREEN 2138 #define MV_ASS_HITRED 2139 +#define MV_BRDCMN_GOR 4735 #define MV_MAN29_BEND 2091 +#define MV_MAN29_HIT 2088 #define MV_MAN29_JUMP 2090 #define MV_MAN29_RUN 2095 #define MV_MAN29_STANDUP 2092 +#define MV_MAN29_STANDUP_NORM 2093 #define MV_PTR_MOVEFAST 2102 #define MV_SHG_HITASS 2151 +#define MV_SHG_HITMAN 2147 +#define MV_SHG_NORM 2117 #define MV_SHR_HITASS 2152 +#define MV_SHR_HITMAN 2149 +#define MV_SHR_NORM 2131 #define MV_STR1_SHOOT 2109 #define MV_STR2_SHOOT 2112 #define PIC_SC29_LTRUBA 2081 +#define QU_SC29_BRD1 4741 +#define QU_SC29_BRD2 4742 +#define QU_SC29_BRDOUT1 4743 +#define QU_SC29_BRDOUT2 4744 #define QU_SC29_ESCAPE 2129 #define QU_SC29_MANFROM_L 2101 #define QU_SC29_MANFROM_R 2104 #define QU_SC29_MANTO_L 2103 #define QU_SC29_MANTO_R 2100 +#define SND_29_014 4348 +#define SND_29_027 4757 #define SND_29_028 4758 #define SND_29_029 4759 #define ST_ASS_NORM 2122 +#define ST_BRDCMN_GOR 4734 +#define ST_BRDCMN_RIGHT 4732 #define ST_MAN29_RUNR 2140 +#define ST_MAN29_SITR 2141 #define ST_STR1_RIGHT 2143 #define ST_STR2_RIGHT 2144 #define ST_STR1_STAND 2110 diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp index 4446af7b60..246510e227 100644 --- a/engines/fullpipe/fullpipe.cpp +++ b/engines/fullpipe/fullpipe.cpp @@ -71,6 +71,7 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc) _flgSoundList = true; _sfxVolume = 0; + _musicVolume = 0; _inputController = 0; _inputDisabled = false; @@ -95,6 +96,7 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc) _gamePaused = false; _inputArFlag = false; _recordEvents = false; + _mainMenu_debugEnabled = false; _flgGameIsRunning = true; @@ -190,6 +192,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 17a771bd5d..5718b16ab3 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; } @@ -125,6 +126,7 @@ public: bool _flgGameIsRunning; bool _inputArFlag; bool _recordEvents; + bool _mainMenu_debugEnabled; Common::Rect _sceneRect; int _sceneWidth; @@ -159,8 +161,10 @@ public: void stopAllSoundStreams(); void stopAllSoundInstances(int id); void updateSoundVolume(); + void setMusicVolume(int vol); int _sfxVolume; + int _musicVolume; GlobalMessageQueueList *_globalMessageQueueList; MessageHandler *_messageHandlers; diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp index 137af86f48..7c66a9a747 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) { @@ -159,7 +168,9 @@ PictureObject::PictureObject() { } PictureObject::~PictureObject() { - warning("STUB: PictureObject::~PictureObject()"); + delete _picture; + _pictureObject2List->clear(); + delete _pictureObject2List; } PictureObject::PictureObject(PictureObject *src) : GameObject(src) { diff --git a/engines/fullpipe/interaction.cpp b/engines/fullpipe/interaction.cpp index 6b6ceb6eeb..84e9688e30 100644 --- a/engines/fullpipe/interaction.cpp +++ b/engines/fullpipe/interaction.cpp @@ -56,7 +56,9 @@ bool canInteractAny(GameObject *obj1, GameObject *obj2, int invId) { } InteractionController::~InteractionController() { - warning("STUB: InteractionController::~InteractionController()"); + _interactions.clear(); + + removeMessageHandler(124, -1); } bool InteractionController::load(MfcArchive &file) { @@ -427,7 +429,14 @@ Interaction::Interaction() { } Interaction::~Interaction() { - warning("STUB: Interaction::~Interaction()"); + if (_messageQueue) { + while (_messageQueue->getExCommandByIndex(0)) + _messageQueue->deleteExCommandByIndex(0, 1); + } + + delete _messageQueue; + + free(_actionName); } bool Interaction::load(MfcArchive &file) { diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp index cfe8adf86f..e79f9c54df 100644 --- a/engines/fullpipe/inventory.cpp +++ b/engines/fullpipe/inventory.cpp @@ -447,6 +447,15 @@ int Inventory2::getHoveredItem(Common::Point *point) { return 0; } +void Inventory2::clear() { + unselectItem(0); + + for (uint i = 0; i < _inventoryItems.size(); i++) + getInventoryPoolItemFieldCById(_inventoryItems[i]->itemId); + + _inventoryItems.clear(); +} + void FullpipeEngine::getAllInventory() { Inventory2 *inv = getGameLoaderInventory(); diff --git a/engines/fullpipe/inventory.h b/engines/fullpipe/inventory.h index 833cccc355..46b55c5669 100644 --- a/engines/fullpipe/inventory.h +++ b/engines/fullpipe/inventory.h @@ -129,6 +129,8 @@ class Inventory2 : public Inventory { bool unselectItem(bool flag); void draw(); + + void clear(); }; } // End of namespace Fullpipe 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 603aaff026..65274bfcf1 100644 --- a/engines/fullpipe/modal.cpp +++ b/engines/fullpipe/modal.cpp @@ -21,12 +21,13 @@ */ #include "fullpipe/fullpipe.h" -#include "fullpipe/modal.h" #include "fullpipe/messages.h" #include "fullpipe/constants.h" #include "fullpipe/motion.h" #include "fullpipe/scenes.h" #include "fullpipe/gameloader.h" +#include "fullpipe/statics.h" +#include "fullpipe/modal.h" #include "fullpipe/constants.h" @@ -718,7 +719,7 @@ bool ModalCredits::init(int counterdiff) { g_fp->_modalObject = menu; - menu->_field_34 = 1; + menu->_mfield_34 = 1; } return true; @@ -750,9 +751,513 @@ void ModalCredits::update() { } ModalMainMenu::ModalMainMenu() { - warning("STUB: ModalMainMenu::ModalMainMenu()"); + _areas.clear(); + + _lastArea = 0; + _hoverAreaId = 0; + _mfield_34 = 0; + _scene = g_fp->accessScene(SC_MAINMENU); + _debugKeyCount = 0; + _sliderOffset = 0; + _screct.left = g_fp->_sceneRect.left; + _screct.top = g_fp->_sceneRect.top; + _screct.right = g_fp->_sceneRect.right; + _screct.bottom = g_fp->_sceneRect.bottom; + + if (g_fp->_currentScene) { + _bgX = g_fp->_currentScene->_x; + _bgY = g_fp->_currentScene->_y; + } else { + _bgX = 0; + _bgY = 0; + } + + g_fp->_sceneRect.top = 0; + g_fp->_sceneRect.left = 0; + g_fp->_sceneRect.right = 800; + g_fp->_sceneRect.bottom = 600; + + MenuArea *area; + + area = new MenuArea(); + area->picIdL = PIC_MNU_EXIT_L; + area->picObjD = 0; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + + area = new MenuArea(); + area->picIdL = PIC_MNU_CONTINUE_L; + area->picObjD = 0; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + + if (isSaveAllowed()) { + area = new MenuArea(); + area->picIdL = PIC_MNU_SAVE_L; + area->picObjD = 0; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + } + + area = new MenuArea(); + area->picIdL = PIC_MNU_LOAD_L; + area->picObjD = 0; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + + area = new MenuArea(); + area->picIdL = PIC_MNU_RESTART_L; + area->picObjD = 0; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + + area = new MenuArea(); + area->picIdL = PIC_MNU_AUTHORS_L; + area->picObjD = 0; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + + area = new MenuArea(); + area->picIdL = PIC_MNU_SLIDER_L; + area->picObjD = _scene->getPictureObjectById(PIC_MNU_SLIDER_D, 0); + area->picObjD->_flags |= 4; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + _menuSliderIdx = _areas.size() - 1; + + area = new MenuArea(); + area->picIdL = PIC_MNU_MUSICSLIDER_L; + area->picObjD = _scene->getPictureObjectById(PIC_MNU_MUSICSLIDER_D, 0); + area->picObjD->_flags |= 4; + area->picObjL = _scene->getPictureObjectById(area->picIdL, 0); + area->picObjL->_flags &= 0xFFFB; + _areas.push_back(area); + _musicSliderIdx = _areas.size() - 1; + + if (g_fp->_mainMenu_debugEnabled) + enableDebugMenuButton(); + + 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, (PictureObject *)_scene->_picObjList[0], 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() { + if (g_fp->_soundEnabled ) { + for (int s = 0; s < g_fp->_currSoundListCount; s++) + for (int i = 0; i < g_fp->_currSoundList1[s]->getCount(); i++) { + updateSoundVolume(g_fp->_currSoundList1[s]->getSoundByIndex(i)); + } + } +} + +void ModalMainMenu::updateSoundVolume(Sound *snd) { + if (!snd->_objectId) + return; + + StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(snd->_objectId, -1); + if (!ani) + return; + + int a, b; + + if (ani->_ox >= _screct.left) { + int par, pan; + + if (ani->_ox <= _screct.right) { + int dx; + + if (ani->_oy <= _screct.bottom) { + if (ani->_oy >= _screct.top) { + snd->setPanAndVolume(g_fp->_sfxVolume, 0); + + return; + } + dx = _screct.top - ani->_oy; + } else { + dx = ani->_oy - _screct.bottom; + } + + par = 0; + + if (dx > 800) { + snd->setPanAndVolume(-3500, 0); + return; + } + + pan = -3500; + a = g_fp->_sfxVolume - (-3500); + b = 800 - dx; + } else { + int dx = ani->_ox - _screct.right; + + if (dx > 800) { + snd->setPanAndVolume(-3500, 0); + return; + } + + pan = -3500; + par = dx * (-3500) / -800; + a = g_fp->_sfxVolume - (-3500); + b = 800 - dx; + } + + int32 pp = b * a; //(0x51EB851F * b * a) >> 32) >> 8; // TODO FIXME + + snd->setPanAndVolume(pan + (pp >> 31) + pp, par); + + return; + } + + int dx = _screct.left - ani->_ox; + if (dx <= 800) { + int32 s = 0x51EB851F * (800 - dx) * (g_fp->_sfxVolume - (-3500)); // TODO FIXME + int32 p = -3500 + (s >> 31) + (s >> 8); + + if (p > g_fp->_sfxVolume) + p = g_fp->_sfxVolume; - _field_34 = 0; + snd->setPanAndVolume(p, dx * (-3500) / 800); + } else { + snd->setPanAndVolume(-3500, 0); + } + + warning("STUB: ModalMainMenu::updateSoundVolume()"); +} + +void ModalMainMenu::updateSliderPos() { + if (_lastArea->picIdL == PIC_MNU_SLIDER_L) { + int x = g_fp->_mouseScreenPos.x + _sliderOffset; + + if (x >= 65) { + if (x > 238) + x = 238; + } else { + x = 65; + } + + _lastArea->picObjD->setOXY(x, _lastArea->picObjD->_oy); + _lastArea->picObjL->setOXY(x, _lastArea->picObjD->_oy); + + int vol = 1000 * (3 * x - 195); + g_fp->_sfxVolume = vol / 173 - 3000; + + if (!(vol / 173)) + g_fp->_sfxVolume = -10000; + + g_fp->updateSoundVolume(); + } else if (_lastArea->picIdL == PIC_MNU_MUSICSLIDER_L) { + int x = g_fp->_mouseScreenPos.x + _sliderOffset; + + if (x >= 65) { + if (x > 238) + x = 238; + } else { + x = 65; + } + + _lastArea->picObjD->setOXY(x, _lastArea->picObjD->_oy); + _lastArea->picObjL->setOXY(x, _lastArea->picObjD->_oy); + + g_fp->setMusicVolume(255 * (x - 65) / 173); + } +} + +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() { + if (!g_fp->_isSaveAllowed) + return false; + + if (g_fp->_aniMan->_flags & 0x100) + return false; + + for (Common::Array<MessageQueue *>::iterator s = g_fp->_globalMessageQueueList->begin(); s != g_fp->_globalMessageQueueList->end(); ++s) { + if (!(*s)->_isFinished && ((*s)->getFlags() & 1)) + return false; + } + + 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() { + 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() { + int x = 173 * (g_fp->_sfxVolume + 3000) / 3000 + 65; + PictureObject *obj = _areas[_menuSliderIdx]->picObjD; + + if (x >= 65) { + if (x > 238) + x = 238; + } else { + x = 65; + } + + obj->setOXY(x, obj->_oy); + _areas[_menuSliderIdx]->picObjL->setOXY(x, obj->_oy); + + x = 173 * g_fp->_musicVolume / 255 + 65; + obj = _areas[_musicSliderIdx]->picObjD; + + if (x >= 65) { + if (x > 238) + x = 238; + } else { + x = 65; + } + + obj->setOXY(x, obj->_oy); + _areas[_musicSliderIdx]->picObjL->setOXY(x, obj->_oy); } ModalHelp::ModalHelp() { @@ -816,6 +1321,145 @@ void ModalHelp::launch() { } } +ModalQuery::ModalQuery() { + _picObjList = 0; + _bg = 0; + _okBtn = 0; + _cancelBtn = 0; + _queryResult = -1; +} + +ModalQuery::~ModalQuery() { + _bg->_flags &= 0xFFFB; + _cancelBtn->_flags &= 0xFFFB; + _okBtn->_flags &= 0xFFFB; +} + +bool ModalQuery::create(Scene *sc, PictureObject *picObjList, int id) { + if (id == PIC_MEX_BGR) { + _bg = sc->getPictureObjectById(PIC_MEX_BGR, 0); + + if (!_bg) + return false; + + _okBtn = sc->getPictureObjectById(PIC_MEX_OK, 0); + + if (!_okBtn) + return false; + + _cancelBtn = sc->getPictureObjectById(PIC_MEX_CANCEL, 0); + + if (!_cancelBtn) + return 0; + } else { + if (id != PIC_MOV_BGR) + return false; + + _bg = sc->getPictureObjectById(PIC_MOV_BGR, 0); + + if (!_bg) + return false; + + _okBtn = sc->getPictureObjectById(PIC_MOV_OK, 0); + + if (!_okBtn) + return false; + + _cancelBtn = sc->getPictureObjectById(PIC_MOV_CANCEL, 0); + + if (!_cancelBtn) + return false; + } + + _queryResult = -1; + _picObjList = picObjList; + + return true; +} + +void ModalQuery::update() { + if (_picObjList) + _picObjList->draw(); + + _bg->draw(); + + if (_okBtn->_flags & 4) + _okBtn->draw(); + + if (_cancelBtn->_flags & 4) + _cancelBtn->draw(); +} + +bool ModalQuery::handleMessage(ExCommand *cmd) { + if (cmd->_messageKind == 17) { + if (cmd->_messageNum == 29) { + if (_okBtn->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y)) { + _queryResult = 1; + + return false; + } + + if (_cancelBtn->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y)) + _queryResult = 0; + } else if (cmd->_messageNum == 36 && cmd->_keyCode == 27) { + _queryResult = 0; + + return false; + } + } + + return false; +} + +bool ModalQuery::init(int counterdiff) { + if (_okBtn->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y)) + _okBtn->_flags |= 4; + else + _okBtn->_flags &= 0xFFFB; + + if (_cancelBtn->isPointInside(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y)) + _cancelBtn->_flags |= 4; + else + _cancelBtn->_flags &= 0xFFFB; + + if (_queryResult == -1) { + return true; + } else { + if (_bg->_id == PIC_MEX_BGR) { + _cancelBtn->_flags &= 0xFFFB; + _okBtn->_flags &= 0xFFFB; + + if (_queryResult == 1) { + warning("STUB: ModalQuery::init()"); + //sceneFade(g_vrtDrawHandle, (Scene *)this->_picObjList, 0); + + //if (inputArFlag) { + // g_needRestart = 1; + // return 0; + //} + //SendMessageA(hwndCallback, WM_DESTROY, 0, 0); + } + } + } + + return false; +} + +ModalSaveGame::ModalSaveGame() { + warning("STUB: ModalSaveGame::ModalSaveGame()"); + + _oldBgX = 0; + _oldBgY = 0; +} + +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 7ed433b125..f7264057fb 100644 --- a/engines/fullpipe/modal.h +++ b/engines/fullpipe/modal.h @@ -27,6 +27,7 @@ namespace Fullpipe { class PictureObject; class Picture; +class Sound; class BaseModalObject { public: @@ -147,19 +148,47 @@ class ModalCredits : public BaseModalObject { virtual void saveload() {} }; +struct MenuArea { + int picIdL; + PictureObject *picObjD; + PictureObject *picObjL; +}; + class ModalMainMenu : public BaseModalObject { public: - int _field_34; + Scene *_scene; + int _hoverAreaId; + Common::Array<MenuArea *> _areas; + int _menuSliderIdx; + int _musicSliderIdx; + MenuArea *_lastArea; + int _sliderOffset; + int _mfield_34; + Common::Rect _screct; + int _bgX; + int _bgY; + 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 updateSoundVolume(Sound *snd); + void updateSliderPos(); + bool isOverArea(PictureObject *obj, Common::Point *point); }; class ModalHelp : public BaseModalObject { @@ -187,13 +216,25 @@ public: class ModalQuery : public BaseModalObject { public: ModalQuery(); - virtual ~ModalQuery() {} + virtual ~ModalQuery(); 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() {} + + bool create(Scene *sc, PictureObject *picObjList, int picId); + int getQueryResult() { return _queryResult; } + + +private: + PictureObject *_picObjList; + PictureObject *_bg; + PictureObject *_okBtn; + PictureObject *_cancelBtn; + int _queryResult; + }; class ModalSaveGame : public BaseModalObject { @@ -206,6 +247,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/motion.cpp b/engines/fullpipe/motion.cpp index 0881a19692..0dcb0ac2cf 100644 --- a/engines/fullpipe/motion.cpp +++ b/engines/fullpipe/motion.cpp @@ -159,10 +159,72 @@ void MctlCompound::freeItems() { _motionControllers[i]->_motionControllerObj->freeItems(); } -MessageQueue *MctlCompound::method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { - warning("STUB: MctlCompound::method34()"); +MessageQueue *MctlCompound::method34(StaticANIObject *ani, int sourceX, int sourceY, int fuzzyMatch, int staticsId) { + int idx = -1; + int sourceIdx = -1; - return 0; + if (!ani) + return 0; + + for (uint i = 0; i < _motionControllers.size(); i++) { + if (_motionControllers[i]->_movGraphReactObj) { + if (_motionControllers[i]->_movGraphReactObj->pointInRegion(ani->_ox, ani->_oy)) { + idx = i; + break; + } + } + } + + for (uint i = 0; i < _motionControllers.size(); i++) { + if (_motionControllers[i]->_movGraphReactObj) { + if (_motionControllers[i]->_movGraphReactObj->pointInRegion(sourceX, sourceY)) { + sourceIdx = i; + break; + } + } + } + + if (idx == -1) + return 0; + + if (sourceIdx == -1) + return 0; + + if (idx == sourceIdx) + return _motionControllers[idx]->_motionControllerObj->method34(ani, sourceX, sourceY, fuzzyMatch, staticsId); + + MctlConnectionPoint *cp = findClosestConnectionPoint(ani->_ox, ani->_oy, idx, sourceX, sourceY, sourceIdx, &sourceIdx); + + if (!cp) + return 0; + + MessageQueue *mq = _motionControllers[idx]->_motionControllerObj->doWalkTo(ani, cp->_connectionX, cp->_connectionY, 1, cp->_field_14); + + if (!mq) + return 0; + + for (uint i = 0; i < cp->_messageQueueObj->getCount(); i++) { + ExCommand *ex = new ExCommand(cp->_messageQueueObj->getExCommandByIndex(i)); + + ex->_excFlags |= 2; + + mq->addExCommandToEnd(ex); + } + + ExCommand *ex = new ExCommand(ani->_id, 51, 0, sourceX, sourceY, 0, 1, 0, 0, 0); + + ex->_excFlags |= 2; + ex->_field_20 = fuzzyMatch; + ex->_keyCode = ani->_okeyCode; + + mq->addExCommandToEnd(ex); + + if (!mq->chain(ani)) { + delete mq; + return 0; + } + + return mq; } MessageQueue *MctlCompound::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { @@ -598,6 +660,14 @@ void MovGraph::calcNodeDistancesAndAngles() { } } +int MovGraph::getItemIndexByStaticAni(StaticANIObject *ani) { + for (uint i = 0; i < _items.size(); i++) + if (_items[i]->ani == ani) + return i; + + return -1; +} + int MovGraph2::getItemIndexByGameObjectId(int objectId) { for (uint i = 0; i < _items2.size(); i++) if (_items2[i]->_objectId == objectId) @@ -2112,6 +2182,91 @@ void MGM::clearMovements2(int idx) { } int MGM::recalcOffsets(int idx, int st1idx, int st2idx, bool flip, bool flop) { +#if 0 + MGMItem *item = _items[idx]; + int subIdx = st1idx + st2idx * item->staticsListCount; + + if (st1idx == st2idx) { + memset(&item->subItems[subIdx], 0, sizeof(item->subItems[subIdx])); + return 0; + } + + if (item->subItems[subIdx]) + return item->subItems[subIdx]->field_8; + + Common::Point point; + + for (int i = 0; i < item->movementListCount; i++) { + mov = item->movements1[i]; + + if (mov->_staticsObj1 == item->statics[st1idx]) { + if (!item->movements2[i] && (!flop || mov->_field_50)) { + item->movements2[i] = 1; + + int stidx = getStaticsIndex(idx, item->movements1[i]->_staticsObj2); + int recalc = recalcOffsets(idx, stidx, st2idx, flip, flop); + + int sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size(); + + v20 = sz + *(&item->subItems[stidx].field_C + 6 * st2idx * _items[idx].staticsListCount); + + if (recalc >= 0) { + if (!item->subItems[subIdx].movement || item->subItems[subIdx].field_8 > recalc + 1 || + (item->subItems[subIdx].field_8 == recalc + 1 && item->subItems[subIdx].field_C > v20) { + item->subItems[subIdx].movement = mov; + item->subItems[subIdx].staticsIndex = stidx; + item->subItems[subIdx].field_8 = recalc + 1; + item->subItems[subIdx].field_C = v20; + + mov->calcSomeXY(&point, 0); + + v25 = point.x + *(&item->subItems[stidx]->x + 6 * st2idx * _items[idx]->staticsListCount); + v26 = point.y + *(&item->subItems[stidx]->y + 6 * st2idx * _items[idx]->staticsListCount); + + item->subItems[subIdx]->x = v25; + item->subItems[subIdx]->y = v26; + } + } + } + } else if (flip) { + if (mov->_staticsObj2 == item->statics[st1idx]) { + if (!item->movements2[i] && (!flop || mov->_field_50)) { + item->movements2[i] = 1; + + int stidx = getStaticsIndex(idx, mov->_staticsObj1); + int recalc = recalcOffsets(idx, stidx, st2idx, flip, flop); + + if (recalc >= 0) { + if (!item->subItems[subIdx]->movement || item->subItems[subIdx]->field_8 > recalc + 1) { + item->subItems[subIdx]->movement = mov; + item->subItems[subIdx].staticsIndex = stidx; + item->subItems[subIdx].field_8 = recalc + 1; + + int sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size(); + + item->subItems[subIdx].field_C = sz + *(&item->subItems[stidx].field_C + 6 * st2idx * _items[idx].staticsListCount); + + mov->calcSomeXY(&point, 0); + + v25 = *(&item->subItems[stidx].x + 6 * st2idx * _items[idx].staticsListCount) - point.x; + v26 = *(&item->subItems[stidx].y + 6 * st2idx * _items[idx].staticsListCount) - point.y; + + item->subItems[subIdx].x = v25; + item->subItems[subIdx].y = v26; + + continue; + } + } + } + } + } + } + + if (item->subItems[subIdx]->movement) + return item->subItems[subIdx]->field_8; + + return -1; +#endif warning("STUB: MGM::recalcOffsets()"); return 0; diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h index a9695e8094..96442cac51 100644 --- a/engines/fullpipe/motion.h +++ b/engines/fullpipe/motion.h @@ -347,6 +347,7 @@ public: double calcDistance(Common::Point *point, MovGraphLink *link, int fuzzyMatch); void calcNodeDistancesAndAngles(); MovGraphNode *calcOffset(int ox, int oy); + int getItemIndexByStaticAni(StaticANIObject *ani); }; class Movement; diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp index 3fe8704d3b..47c6a3c8cd 100644 --- a/engines/fullpipe/scenes.cpp +++ b/engines/fullpipe/scenes.cpp @@ -378,26 +378,22 @@ Vars::Vars() { scene28_headBeardedFlipper = false; scene28_lift6inside = false; - scene29_var01 = 0; - scene29_var02 = 0; - scene29_var03 = 0; - scene29_var04 = 0; scene29_porter = 0; scene29_shooter1 = 0; scene29_shooter2 = 0; scene29_ass = 0; - scene29_var09 = 0; - scene29_var10 = 0; - scene29_var11 = 0; - scene29_var12 = 0; - scene29_var13 = 0; - scene29_var14 = 75; - scene29_var15 = 0; - scene29_var16 = 0; - scene29_var17 = 0; - scene29_var18 = 0; - scene29_var20 = 0; - scene29_var21 = 0; + scene29_manIsRiding = false; + scene29_arcadeIsOn = false; + scene29_reachedFarRight = false; + scene29_rideBackEnabled = false; + scene29_shootCountdown = 0; + scene29_shootDistance = 75; + scene29_manIsHit = 0; + scene29_scrollSpeed = 0; + scene29_scrollingDisabled = 0; + scene29_hitBall = 0; + scene29_manX = 0; + scene29_manY = 0; scene30_leg = 0; scene30_liftFlag = 1; @@ -1469,5 +1465,31 @@ Ball *BallChain::sub04(Ball *ballP, Ball *ballN) { return pTail; } +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; + } +} + } // End of namespace Fullpipe diff --git a/engines/fullpipe/scenes.h b/engines/fullpipe/scenes.h index ef6af54c0f..0b7c4e7c8f 100644 --- a/engines/fullpipe/scenes.h +++ b/engines/fullpipe/scenes.h @@ -232,6 +232,7 @@ struct BallChain { void init(Ball **ball); Ball *sub04(Ball *ballP, Ball *ballN); + void removeBall(Ball *ball); void reset() { pHead = 0; pTail = 0; field_8 = 0; numBalls = 0; free(cPlex); cPlex = 0; cPlexLen = 0; } }; @@ -590,31 +591,27 @@ public: bool scene28_headBeardedFlipper; bool scene28_lift6inside; - int scene29_var01; - int scene29_var02; - int scene29_var03; - int scene29_var04; StaticANIObject *scene29_porter; StaticANIObject *scene29_shooter1; StaticANIObject *scene29_shooter2; StaticANIObject *scene29_ass; - BallChain scene29_var05; - BallChain scene29_var06; - BallChain scene29_var07; - BallChain scene29_var08; - int scene29_var09; - int scene29_var10; - int scene29_var11; - int scene29_var12; - int scene29_var13; - int scene29_var14; - int scene29_var15; - int scene29_var16; - int scene29_var17; - int scene29_var18; - Common::Array<WalkingBearder *> scene29_var19; - int scene29_var20; - int scene29_var21; + BallChain scene29_balls; + BallChain scene29_redBalls; + BallChain scene29_flyingRedBalls; + BallChain scene29_greenBalls; + bool scene29_manIsRiding; + bool scene29_arcadeIsOn; + bool scene29_reachedFarRight; + bool scene29_rideBackEnabled; + int scene29_shootCountdown; + int scene29_shootDistance; + int scene29_manIsHit; + int scene29_scrollSpeed; + bool scene29_scrollingDisabled; + int scene29_hitBall; + Common::Array<WalkingBearder *> scene29_bearders; + int scene29_manX; + int scene29_manY; MGM scene29_mgm; StaticANIObject *scene30_leg; diff --git a/engines/fullpipe/scenes/scene29.cpp b/engines/fullpipe/scenes/scene29.cpp index 27fc09adce..2d5127137d 100644 --- a/engines/fullpipe/scenes/scene29.cpp +++ b/engines/fullpipe/scenes/scene29.cpp @@ -43,105 +43,101 @@ struct WalkingBearder { }; void scene29_initScene(Scene *sc) { - g_vars->scene29_var01 = 300; - g_vars->scene29_var02 = 200; - g_vars->scene29_var03 = 400; - g_vars->scene29_var04 = 300; g_vars->scene29_porter = sc->getStaticANIObject1ById(ANI_PORTER, -1); g_vars->scene29_shooter1 = sc->getStaticANIObject1ById(ANI_SHOOTER1, -1); g_vars->scene29_shooter2 = sc->getStaticANIObject1ById(ANI_SHOOTER2, -1); g_vars->scene29_ass = sc->getStaticANIObject1ById(ANI_ASS, -1); - g_vars->scene29_var05.numBalls = 0; - g_vars->scene29_var05.pTail = 0; - g_vars->scene29_var05.field_8 = 0; - g_vars->scene29_var05.pHead = 0; + g_vars->scene29_balls.numBalls = 0; + g_vars->scene29_balls.pTail = 0; + g_vars->scene29_balls.field_8 = 0; + g_vars->scene29_balls.pHead = 0; - free(g_vars->scene29_var05.cPlex); - g_vars->scene29_var05.cPlex = 0; + free(g_vars->scene29_balls.cPlex); + g_vars->scene29_balls.cPlex = 0; StaticANIObject *ani; - g_vars->scene29_var08.numBalls = 0; - g_vars->scene29_var08.pTail = 0; - g_vars->scene29_var08.field_8 = 0; - g_vars->scene29_var08.pHead = 0; + g_vars->scene29_greenBalls.numBalls = 0; + g_vars->scene29_greenBalls.pTail = 0; + g_vars->scene29_greenBalls.field_8 = 0; + g_vars->scene29_greenBalls.pHead = 0; - free(g_vars->scene29_var08.cPlex); - g_vars->scene29_var08.cPlex = 0; + free(g_vars->scene29_greenBalls.cPlex); + g_vars->scene29_greenBalls.cPlex = 0; ani = sc->getStaticANIObject1ById(ANI_SHELL_GREEN, -1); - Ball *b = g_vars->scene29_var05.sub04(g_vars->scene29_var05.field_8, 0); + Ball *b = g_vars->scene29_balls.sub04(g_vars->scene29_balls.field_8, 0); b->ani = ani; - if (g_vars->scene29_var05.field_8) - g_vars->scene29_var05.field_8->p0 = b; + if (g_vars->scene29_balls.field_8) + g_vars->scene29_balls.field_8->p0 = b; else - g_vars->scene29_var05.pHead = b; + g_vars->scene29_balls.pHead = b; - g_vars->scene29_var05.field_8 = b; + g_vars->scene29_balls.field_8 = b; for (int i = 0; i < 2; i++) { StaticANIObject *newani = new StaticANIObject(ani); sc->addStaticANIObject(newani, 1); - b = g_vars->scene29_var05.sub04(g_vars->scene29_var05.field_8, 0); + b = g_vars->scene29_balls.sub04(g_vars->scene29_balls.field_8, 0); b->ani = ani; - if (g_vars->scene29_var05.field_8) - g_vars->scene29_var05.field_8->p0 = b; + if (g_vars->scene29_balls.field_8) + g_vars->scene29_balls.field_8->p0 = b; else - g_vars->scene29_var05.pHead = b; + g_vars->scene29_balls.pHead = b; - g_vars->scene29_var05.field_8 = b; + g_vars->scene29_balls.field_8 = b; } - g_vars->scene29_var06.numBalls = 0; - g_vars->scene29_var06.pTail = 0; - g_vars->scene29_var06.field_8 = 0; - g_vars->scene29_var06.pHead = 0; + g_vars->scene29_redBalls.numBalls = 0; + g_vars->scene29_redBalls.pTail = 0; + g_vars->scene29_redBalls.field_8 = 0; + g_vars->scene29_redBalls.pHead = 0; - free(g_vars->scene29_var06.cPlex); - g_vars->scene29_var06.cPlex = 0; + free(g_vars->scene29_redBalls.cPlex); + g_vars->scene29_redBalls.cPlex = 0; - g_vars->scene29_var07.numBalls = 0; - g_vars->scene29_var07.pTail = 0; - g_vars->scene29_var07.field_8 = 0; - g_vars->scene29_var07.pHead = 0; + g_vars->scene29_flyingRedBalls.numBalls = 0; + g_vars->scene29_flyingRedBalls.pTail = 0; + g_vars->scene29_flyingRedBalls.field_8 = 0; + g_vars->scene29_flyingRedBalls.pHead = 0; - free(g_vars->scene29_var07.cPlex); - g_vars->scene29_var07.cPlex = 0; + free(g_vars->scene29_flyingRedBalls.cPlex); + g_vars->scene29_flyingRedBalls.cPlex = 0; ani = sc->getStaticANIObject1ById(ANI_SHELL_RED, -1); - b = g_vars->scene29_var06.sub04(g_vars->scene29_var06.field_8, 0); + b = g_vars->scene29_redBalls.sub04(g_vars->scene29_redBalls.field_8, 0); b->ani = ani; - if (g_vars->scene29_var06.field_8) - g_vars->scene29_var06.field_8->p0 = b; + if (g_vars->scene29_redBalls.field_8) + g_vars->scene29_redBalls.field_8->p0 = b; else - g_vars->scene29_var06.pHead = b; + g_vars->scene29_redBalls.pHead = b; - g_vars->scene29_var06.field_8 = b; + g_vars->scene29_redBalls.field_8 = b; for (int i = 0; i < 2; i++) { StaticANIObject *newani = new StaticANIObject(ani); sc->addStaticANIObject(newani, 1); - b = g_vars->scene29_var06.sub04(g_vars->scene29_var06.field_8, 0); + b = g_vars->scene29_redBalls.sub04(g_vars->scene29_redBalls.field_8, 0); b->ani = ani; - if (g_vars->scene29_var06.field_8) - g_vars->scene29_var06.field_8->p0 = b; + if (g_vars->scene29_redBalls.field_8) + g_vars->scene29_redBalls.field_8->p0 = b; else - g_vars->scene29_var06.pHead = b; + g_vars->scene29_redBalls.pHead = b; - g_vars->scene29_var06.field_8 = b; + g_vars->scene29_redBalls.field_8 = b; } - g_vars->scene29_var19.clear(); + g_vars->scene29_bearders.clear(); ani = new StaticANIObject(g_fp->accessScene(SC_COMMON)->getStaticANIObject1ById(ANI_BEARDED_CMN, -1)); @@ -155,77 +151,551 @@ void scene29_initScene(Scene *sc) { wb->wbflag = 0; wb->wbcounter = 0; - g_vars->scene29_var19.push_back(wb); + g_vars->scene29_bearders.push_back(wb); - g_vars->scene29_var09 = 0; - g_vars->scene29_var10 = 0; - g_vars->scene29_var11 = 0; - g_vars->scene29_var12 = 0; - g_vars->scene29_var13 = 0; - g_vars->scene29_var14 = 75; - g_vars->scene29_var15 = 0; - g_vars->scene29_var16 = 0; - g_vars->scene29_var17 = 0; - g_vars->scene29_var18 = 0; + g_vars->scene29_manIsRiding = false; + g_vars->scene29_arcadeIsOn = false; + g_vars->scene29_reachedFarRight = false; + g_vars->scene29_rideBackEnabled = false; + g_vars->scene29_shootCountdown = 0; + g_vars->scene29_shootDistance = 75; + g_vars->scene29_manIsHit = false; + g_vars->scene29_scrollSpeed = 0; + g_vars->scene29_scrollingDisabled = false; + g_vars->scene29_hitBall = 0; g_fp->setArcadeOverlay(PIC_CSR_ARCADE8); } void sceneHandler29_winArcade() { - warning("STUB: sceneHandler29_winArcade()"); + if (g_vars->scene29_shooter2->_flags & 4) { + g_vars->scene29_shootCountdown = 0; + + g_vars->scene29_shooter1->changeStatics2(ST_STR1_STAND); + g_vars->scene29_shooter2->changeStatics2(ST_STR2_STAND); + + g_vars->scene29_shooter2->_flags &= 0xFFFB; + + StaticANIObject *ani; + Ball *newball, *ball, *oldp0; + + while (g_vars->scene29_greenBalls.numBalls) { + ball = g_vars->scene29_greenBalls.pHead; + ani = g_vars->scene29_greenBalls.pHead->ani; + oldp0 = g_vars->scene29_greenBalls.pHead->p0; + g_vars->scene29_greenBalls.pHead = g_vars->scene29_greenBalls.pHead->p0; + + if (g_vars->scene29_greenBalls.pHead) + oldp0->p1 = 0; + else + g_vars->scene29_greenBalls.field_8 = 0; + + ball->p0 = g_vars->scene29_greenBalls.pTail; + g_vars->scene29_greenBalls.pTail = ball; + g_vars->scene29_greenBalls.numBalls--; + + if (!g_vars->scene29_greenBalls.numBalls) + g_vars->scene29_greenBalls.reset(); + + ani->hide(); + + newball = g_vars->scene29_balls.sub04(g_vars->scene29_balls.field_8, 0); + newball->ani = ani; + + if (g_vars->scene29_balls.field_8) + g_vars->scene29_balls.field_8->p0 = newball; + else + g_vars->scene29_balls.pHead = newball; + + g_vars->scene29_balls.field_8 = newball; + } + + while (g_vars->scene29_flyingRedBalls.numBalls) { + ball = g_vars->scene29_flyingRedBalls.pHead; + ani = g_vars->scene29_flyingRedBalls.pHead->ani; + oldp0 = g_vars->scene29_flyingRedBalls.pHead->p0; + g_vars->scene29_flyingRedBalls.pHead = g_vars->scene29_flyingRedBalls.pHead->p0; + + if (g_vars->scene29_flyingRedBalls.pHead) + oldp0->p1 = 0; + else + g_vars->scene29_flyingRedBalls.field_8 = 0; + + ball->p0 = g_vars->scene29_flyingRedBalls.pTail; + g_vars->scene29_flyingRedBalls.pTail = ball; + g_vars->scene29_flyingRedBalls.numBalls--; + + if (!g_vars->scene29_flyingRedBalls.numBalls) { + g_vars->scene29_flyingRedBalls.numBalls = 0; + g_vars->scene29_flyingRedBalls.pTail = 0; + g_vars->scene29_flyingRedBalls.field_8 = 0; + g_vars->scene29_flyingRedBalls.pHead = 0; + + free(g_vars->scene29_flyingRedBalls.cPlex); + + g_vars->scene29_flyingRedBalls.cPlex = 0; + } + + ani->hide(); + + newball = g_vars->scene29_redBalls.sub04(g_vars->scene29_redBalls.field_8, 0); + newball->ani = ani; + + if (g_vars->scene29_redBalls.field_8) + g_vars->scene29_redBalls.field_8->p0 = newball; + else + g_vars->scene29_redBalls.pHead = newball; + + g_vars->scene29_redBalls.field_8 = newball; + } + + g_vars->scene29_ass->queueMessageQueue(0); + g_vars->scene29_ass->_flags &= 0xFFFB; + + chainQueue(QU_SC29_ESCAPE, 1); + } + + g_fp->setObjectState(sO_LeftPipe_29, g_fp->getObjectEnumState(sO_LeftPipe_29, sO_IsOpened)); } void sceneHandler29_shootGreen() { - warning("STUB: sceneHandler29_shootGreen()"); + if (g_vars->scene29_balls.numBalls) { + int x = g_vars->scene29_shooter1->_ox - 113; + int y = g_vars->scene29_shooter1->_oy - 48; + StaticANIObject *ani = g_vars->scene29_balls.pHead->ani; + Ball *oldhead = g_vars->scene29_balls.pHead; + Ball *oldp0 = g_vars->scene29_balls.pHead->p0; + + g_vars->scene29_balls.pHead = g_vars->scene29_balls.pHead->p0; + + if (g_vars->scene29_balls.pHead) + oldp0->p1 = 0; + else + g_vars->scene29_balls.field_8 = 0; + + oldhead->p0 = g_vars->scene29_balls.pTail; + + g_vars->scene29_balls.pTail = oldhead; + g_vars->scene29_balls.numBalls--; + + if (!g_vars->scene29_balls.numBalls) { + g_vars->scene29_balls.numBalls = 0; + g_vars->scene29_balls.pTail = 0; + g_vars->scene29_balls.field_8 = 0; + g_vars->scene29_balls.pHead = 0; + + free(g_vars->scene29_balls.cPlex); + g_vars->scene29_balls.cPlex = 0; + } + + ani->show1(x, y, MV_SHG_NORM, 0); + ani->_priority = 5; + + Ball *runPtr = g_vars->scene29_greenBalls.pTail; + Ball *lastP = g_vars->scene29_greenBalls.field_8; + + if (!g_vars->scene29_greenBalls.pTail) { + g_vars->scene29_greenBalls.cPlex = (byte *)calloc(g_vars->scene29_greenBalls.cPlexLen, sizeof(Ball)); + + byte *p1 = g_vars->scene29_greenBalls.cPlex + (g_vars->scene29_greenBalls.cPlexLen - 1) * sizeof(Ball); + + if (g_vars->scene29_greenBalls.cPlexLen - 1 < 0) { + runPtr = g_vars->scene29_greenBalls.pTail; + } else { + runPtr = g_vars->scene29_greenBalls.pTail; + + for (int j = 0; j < g_vars->scene29_greenBalls.cPlexLen; j++) { + ((Ball *)p1)->p1 = runPtr; + runPtr = (Ball *)p1; + + p1 -= sizeof(Ball); + } + + g_vars->scene29_greenBalls.pTail = runPtr; + } + } + g_vars->scene29_greenBalls.pTail = runPtr->p0; + runPtr->p1 = lastP; + runPtr->p0 = 0; + runPtr->ani = ani; + + g_vars->scene29_greenBalls.numBalls++; + + if (g_vars->scene29_greenBalls.field_8) { + g_vars->scene29_greenBalls.field_8->p0 = runPtr; + g_vars->scene29_greenBalls.field_8 = runPtr; + } else { + g_vars->scene29_greenBalls.pHead = runPtr; + g_vars->scene29_greenBalls.field_8 = runPtr; + } + } } void sceneHandler29_shootRed() { - warning("STUB: sceneHandler29_shootRed()"); + if (g_vars->scene29_balls.numBalls) { + int x = g_vars->scene29_shooter1->_ox - 101; + int y = g_vars->scene29_shooter1->_oy - 14; + StaticANIObject *ani = g_vars->scene29_balls.pHead->ani; + Ball *oldhead = g_vars->scene29_balls.pHead; + Ball *oldp0 = g_vars->scene29_balls.pHead->p0; + + g_vars->scene29_balls.pHead = g_vars->scene29_balls.pHead->p0; + + if (g_vars->scene29_balls.pHead) + oldp0->p1 = 0; + else + g_vars->scene29_balls.field_8 = 0; + + oldhead->p0 = g_vars->scene29_balls.pTail; + + g_vars->scene29_balls.pTail = oldhead; + g_vars->scene29_balls.numBalls--; + + if (!g_vars->scene29_balls.numBalls) { + g_vars->scene29_balls.numBalls = 0; + g_vars->scene29_balls.pTail = 0; + g_vars->scene29_balls.field_8 = 0; + g_vars->scene29_balls.pHead = 0; + + free(g_vars->scene29_balls.cPlex); + g_vars->scene29_balls.cPlex = 0; + } + + ani->show1(x, y, MV_SHR_NORM, 0); + ani->_priority = 5; + + Ball *runPtr = g_vars->scene29_flyingRedBalls.pTail; + Ball *lastP = g_vars->scene29_flyingRedBalls.field_8; + + if (!g_vars->scene29_flyingRedBalls.pTail) { + g_vars->scene29_flyingRedBalls.cPlex = (byte *)calloc(g_vars->scene29_flyingRedBalls.cPlexLen, sizeof(Ball)); + + byte *p1 = g_vars->scene29_flyingRedBalls.cPlex + (g_vars->scene29_flyingRedBalls.cPlexLen - 1) * sizeof(Ball); + + if (g_vars->scene29_flyingRedBalls.cPlexLen - 1 < 0) { + runPtr = g_vars->scene29_flyingRedBalls.pTail; + } else { + runPtr = g_vars->scene29_flyingRedBalls.pTail; + + for (int j = 0; j < g_vars->scene29_flyingRedBalls.cPlexLen; j++) { + ((Ball *)p1)->p1 = runPtr; + runPtr = (Ball *)p1; + + p1 -= sizeof(Ball); + } + + g_vars->scene29_flyingRedBalls.pTail = runPtr; + } + } + g_vars->scene29_flyingRedBalls.pTail = runPtr->p0; + runPtr->p1 = lastP; + runPtr->p0 = 0; + runPtr->ani = ani; + + g_vars->scene29_flyingRedBalls.numBalls++; + + if (g_vars->scene29_flyingRedBalls.field_8) { + g_vars->scene29_flyingRedBalls.field_8->p0 = runPtr; + g_vars->scene29_flyingRedBalls.field_8 = runPtr; + } else { + g_vars->scene29_flyingRedBalls.pHead = runPtr; + g_vars->scene29_flyingRedBalls.field_8 = runPtr; + } + } } void sceneHandler29_manJump() { if (!g_fp->_aniMan->_movement || g_fp->_aniMan->_movement->_id == MV_MAN29_RUN || g_fp->_aniMan->_movement->_id == MV_MAN29_STANDUP) { - g_vars->scene29_var12 = 0; - g_vars->scene29_var15 = 0; - g_vars->scene29_var11 = 1; + g_vars->scene29_rideBackEnabled = false; + g_vars->scene29_manIsHit = false; + g_vars->scene29_reachedFarRight = true; g_fp->_aniMan->changeStatics2(ST_MAN29_RUNR); g_fp->_aniMan->startAnim(MV_MAN29_JUMP, 0, -1); } - g_vars->scene29_var20 = g_fp->_aniMan->_ox; - g_vars->scene29_var21 = g_fp->_aniMan->_oy; + g_vars->scene29_manX = g_fp->_aniMan->_ox; + g_vars->scene29_manY = g_fp->_aniMan->_oy; } void sceneHandler29_manBend() { if (!g_fp->_aniMan->_movement || g_fp->_aniMan->_movement->_id == MV_MAN29_RUN || g_fp->_aniMan->_movement->_id == MV_MAN29_STANDUP) { - g_vars->scene29_var12 = 0; - g_vars->scene29_var15 = 0; - g_vars->scene29_var11 = 1; + g_vars->scene29_rideBackEnabled = false; + g_vars->scene29_manIsHit = false; + g_vars->scene29_reachedFarRight = true; g_fp->_aniMan->changeStatics2(ST_MAN29_RUNR); g_fp->_aniMan->startAnim(MV_MAN29_BEND, 0, -1); } - g_vars->scene29_var20 = g_fp->_aniMan->_ox; - g_vars->scene29_var21 = g_fp->_aniMan->_oy; + g_vars->scene29_manX = g_fp->_aniMan->_ox; + g_vars->scene29_manY = g_fp->_aniMan->_oy; +} + +bool sceneHandler29_checkRedBallHit(StaticANIObject *ani, int maxx) { + if (!g_vars->scene29_arcadeIsOn || g_vars->scene29_manIsHit) + return false; + + if ((ani->_ox >= g_vars->scene29_manX + 42 || ani->_ox <= g_vars->scene29_manX + 8) + && (ani->_ox < g_vars->scene29_manX + 8 || maxx > g_vars->scene29_manX + 27)) + return false; + + if (!g_fp->_aniMan->_movement) + return true; + + int phase = g_fp->_aniMan->_movement->_currDynamicPhaseIndex; + + if (g_fp->_aniMan->_movement->_id != MV_MAN29_BEND && g_fp->_aniMan->_movement->_id != MV_MAN29_RUN + && (g_fp->_aniMan->_movement->_id != MV_MAN29_JUMP || (phase >= 3 && phase <= 6))) + return false; + else + return true; +} + +bool sceneHandler29_checkGreenBallHit(StaticANIObject *ani, int maxx) { + if (!g_vars->scene29_arcadeIsOn || g_vars->scene29_manIsHit) + return false; + + if (ani->_ox >= g_vars->scene29_manX + 40) { + if (maxx > g_vars->scene29_manX + 27) + return false; + } else { + if (ani->_ox <= g_vars->scene29_manX + 10) { + if (ani->_ox < g_vars->scene29_manX + 40) + return false; + + if (maxx > g_vars->scene29_manX + 27) + return false; + } + } + + if (!g_fp->_aniMan->_movement) + return true; + + if (g_fp->_aniMan->_movement->_id == MV_MAN29_JUMP) + return true; + + if (g_fp->_aniMan->_movement->_id == MV_MAN29_RUN) + return true; + + if (g_fp->_aniMan->_movement->_id == MV_MAN29_BEND) { + if (g_fp->_aniMan->_movement->_currDynamicPhaseIndex < 1 || g_fp->_aniMan->_movement->_currDynamicPhaseIndex > 5) + return true; + } + + return false; +} + +void sceneHandler29_manHit() { + MGMInfo mgminfo; + + g_vars->scene29_manIsHit = true; + + g_fp->_aniMan->changeStatics2(ST_MAN29_RUNR); + g_fp->_aniMan->setOXY(g_vars->scene29_manX, g_vars->scene29_manY); + + mgminfo.ani = g_fp->_aniMan; + mgminfo.staticsId2 = ST_MAN29_SITR; + mgminfo.y1 = 463; + mgminfo.x1 = g_vars->scene29_manX <= 638 ? 351 : 0; + mgminfo.field_1C = 10; + mgminfo.field_10 = 1; + mgminfo.flags = (g_vars->scene29_manX <= 638 ? 2 : 0) | 0x44; + mgminfo.movementId = MV_MAN29_HIT; + + MessageQueue *mq = g_vars->scene29_mgm.genMovement(&mgminfo); + ExCommand *ex; + + if (mq) { + if (g_vars->scene29_manX <= 638) { + ex = new ExCommand(ANI_MAN, 1, MV_MAN29_STANDUP_NORM, 0, 0, 0, 1, 0, 0, 0); + ex->_excFlags = 2; + ex->_keyCode = g_fp->_aniMan->_okeyCode; + mq->addExCommandToEnd(ex); + + ex = new ExCommand(0, 17, MSG_SC29_STOPRIDE, 0, 0, 0, 1, 0, 0, 0); + ex->_excFlags = 2; + mq->addExCommandToEnd(ex); + + g_vars->scene29_manIsRiding = false; + g_vars->scene29_arcadeIsOn = false; + g_vars->scene29_reachedFarRight = false; + g_vars->scene29_rideBackEnabled = false; + } else { + ex = new ExCommand(ANI_MAN, 1, MV_MAN29_STANDUP, 0, 0, 0, 1, 0, 0, 0); + ex->_excFlags = 2; + ex->_keyCode = g_fp->_aniMan->_okeyCode; + mq->addExCommandToEnd(ex); + } + + mq->setFlags(mq->getFlags() | 1); + + if (!mq->chain(g_fp->_aniMan)) + delete mq; + } +} + +void sceneHandler29_assHitRed() { + if (g_vars->scene29_ass->_statics->_staticsId == ST_ASS_NORM) { + g_vars->scene29_ass->changeStatics2(ST_ASS_NORM); + g_vars->scene29_ass->startAnim(MV_ASS_HITRED, 0, -1); + } +} + +void sceneHandler29_assHitGreen() { + if (g_vars->scene29_ass->_statics->_staticsId == ST_ASS_NORM) { + g_vars->scene29_ass->changeStatics2(ST_ASS_NORM); + g_vars->scene29_ass->startAnim(MV_ASS_HITGREEN, 0, -1); + } } -void sceneHandler29_sub03() { - warning("STUB: sceneHandler29_sub03()"); +void sceneHandler29_ballHitCheck() { + Ball *ball = g_vars->scene29_greenBalls.pHead; + Ball *newball; + int x, y; + + while (ball) { + x = ball->ani->_ox - 30; + y = ball->ani->_oy; + + if (x >= 186) { + if (sceneHandler29_checkGreenBallHit(ball->ani, x)) { + newball = g_vars->scene29_balls.sub04(g_vars->scene29_balls.field_8, 0); + newball->ani = ball->ani; + + if (g_vars->scene29_balls.field_8) + g_vars->scene29_balls.field_8->p0 = newball; + else + g_vars->scene29_balls.pHead = newball; + + g_vars->scene29_balls.field_8 = newball; + + if (ball == g_vars->scene29_greenBalls.pHead) + g_vars->scene29_greenBalls.pHead = ball->p0; + else + ball->p1->p0 = ball->p0; + + if (ball == g_vars->scene29_greenBalls.field_8) + g_vars->scene29_greenBalls.field_8 = ball->p1; + else + ball->p0->p1 = ball->p1; + + g_vars->scene29_greenBalls.init(&ball); + + sceneHandler29_manHit(); + + g_fp->playSound(SND_29_014, 0); + + ball->ani->startAnim(MV_SHG_HITMAN, 0, -1); + + g_vars->scene29_hitBall = ball->ani->_id; + } else { + ball->ani->setOXY(x, y); + } + } else { + newball = g_vars->scene29_balls.sub04(g_vars->scene29_balls.field_8, 0); + newball->ani = ball->ani; + + if (g_vars->scene29_balls.field_8) + g_vars->scene29_balls.field_8->p0 = newball; + else + g_vars->scene29_balls.pHead = newball; + + g_vars->scene29_balls.field_8 = newball; + + ball->ani->hide(); + + if (ball == g_vars->scene29_greenBalls.pHead) + g_vars->scene29_greenBalls.pHead = ball->p0; + else + ball->p1->p0 = ball->p0; + + if (ball == g_vars->scene29_greenBalls.field_8) + g_vars->scene29_greenBalls.field_8 = ball->p1; + else + ball->p0->p1 = ball->p1; + + g_vars->scene29_greenBalls.init(&ball); + + sceneHandler29_assHitGreen(); + } + + ball = ball->p0; + } + + ball = g_vars->scene29_flyingRedBalls.pHead; + + while (ball) { + x = ball->ani->_ox - 30; + y = ball->ani->_oy; + + if (x >= 147) { + if (sceneHandler29_checkRedBallHit(ball->ani, x)) { + newball = g_vars->scene29_redBalls.sub04(g_vars->scene29_redBalls.field_8, 0); + newball->ani = ball->ani; + + if (g_vars->scene29_redBalls.field_8) + g_vars->scene29_redBalls.field_8->p0 = newball; + else + g_vars->scene29_redBalls.pHead = newball; + + g_vars->scene29_redBalls.field_8 = newball; + + g_vars->scene29_flyingRedBalls.removeBall(ball); + + sceneHandler29_manHit(); + + g_fp->playSound(SND_29_027, 0); + + ball->ani->startAnim(MV_SHR_HITMAN, 0, -1); + + g_vars->scene29_hitBall = ball->ani->_id; + } else { + ball->ani->setOXY(x, y); + } + } else { + newball = g_vars->scene29_redBalls.sub04(g_vars->scene29_redBalls.field_8, 0); + newball->ani = ball->ani; + + if (g_vars->scene29_redBalls.field_8) + g_vars->scene29_redBalls.field_8->p0 = newball; + else + g_vars->scene29_redBalls.pHead = newball; + + g_vars->scene29_redBalls.field_8 = newball; + + ball->ani->hide(); + + if (ball == g_vars->scene29_flyingRedBalls.pHead) + g_vars->scene29_flyingRedBalls.pHead = ball->p0; + else + ball->p1->p0 = ball->p0; + + if (ball == g_vars->scene29_flyingRedBalls.field_8) + g_vars->scene29_flyingRedBalls.field_8 = ball->p1; + else + ball->p0->p1 = ball->p1; + + g_vars->scene29_flyingRedBalls.init(&ball); + + sceneHandler29_assHitRed(); + } + + ball = ball->p0; + } } void sceneHandler29_manFromL() { - if (g_vars->scene29_var20 < 497 && !g_vars->scene29_var17) { + if (g_vars->scene29_manX < 497 && !g_vars->scene29_scrollingDisabled) { getCurrSceneSc2MotionController()->setEnabled(); getGameLoaderInteractionController()->enableFlag24(); g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000); chainQueue(QU_SC29_MANFROM_L, 1); - g_vars->scene29_var17 = 1; + g_vars->scene29_scrollingDisabled = true; - g_fp->_scrollSpeed = g_vars->scene29_var16; + g_fp->_scrollSpeed = g_vars->scene29_scrollSpeed; } } @@ -235,14 +705,14 @@ void sceneHandler29_manFromR() { chainQueue(QU_SC29_MANFROM_R, 1); - g_vars->scene29_var10 = 0; - g_vars->scene29_var12 = 0; + g_vars->scene29_arcadeIsOn = false; + g_vars->scene29_rideBackEnabled = false; } int sceneHandler29_updateScreenCallback() { int res; - res = g_fp->drawArcadeOverlay(g_vars->scene29_var10); + res = g_fp->drawArcadeOverlay(g_vars->scene29_arcadeIsOn); if (!res) g_fp->_updateScreenCallback = 0; @@ -256,7 +726,7 @@ void sceneHandler29_manToL() { chainQueue(QU_SC29_MANTO_L, 1); - g_vars->scene29_var10 = 1; + g_vars->scene29_arcadeIsOn = true; g_vars->scene29_mgm.addItem(g_fp->_aniMan->_id); @@ -272,13 +742,13 @@ void sceneHandler29_manToR() { chainQueue(QU_SC29_MANTO_R, 1); - g_vars->scene29_var09 = 1; + g_vars->scene29_manIsRiding = true; g_fp->_msgY = -1; g_fp->_msgX = -1; - g_vars->scene29_var17 = 0; + g_vars->scene29_scrollingDisabled = false; - g_vars->scene29_var16 = g_fp->_scrollSpeed; + g_vars->scene29_scrollSpeed = g_fp->_scrollSpeed; g_fp->_scrollSpeed = 4; } @@ -289,8 +759,8 @@ void sceneHandler29_clickPorter(ExCommand *cmd) { return; } - if (g_vars->scene29_var20 <= g_vars->scene29_porter->_ox) { - if (ABS(351 - g_vars->scene29_var20) > 1 || ABS(443 - g_vars->scene29_var21) > 1 + if (g_vars->scene29_manX <= g_vars->scene29_porter->_ox) { + if (ABS(351 - g_vars->scene29_manX) > 1 || ABS(443 - g_vars->scene29_manY) > 1 || g_fp->_aniMan->_movement || g_fp->_aniMan->_statics->_staticsId != ST_MAN_RIGHT) { if (g_fp->_msgX != 351 || g_fp->_msgY != 443) { MessageQueue *mq = getCurrSceneSc2MotionController()->method34(g_fp->_aniMan, 351, 443, 1, ST_MAN_RIGHT); @@ -305,10 +775,10 @@ void sceneHandler29_clickPorter(ExCommand *cmd) { sceneHandler29_manToL(); } } else { - g_vars->scene29_var20 = g_fp->_aniMan->_ox; - g_vars->scene29_var21 = g_fp->_aniMan->_oy; + g_vars->scene29_manX = g_fp->_aniMan->_ox; + g_vars->scene29_manY = g_fp->_aniMan->_oy; - if (ABS(1582 - g_vars->scene29_var20) > 1 || ABS(445 - g_fp->_aniMan->_oy) > 1 + if (ABS(1582 - g_vars->scene29_manX) > 1 || ABS(445 - g_fp->_aniMan->_oy) > 1 || g_fp->_aniMan->_movement || g_fp->_aniMan->_statics->_staticsId != (0x4000 | ST_MAN_RIGHT)) { if (g_fp->_msgX != 1582 || g_fp->_msgY != 445) { MessageQueue *mq = getCurrSceneSc2MotionController()->method34(g_fp->_aniMan, 1582, 445, 1, (0x4000 | ST_MAN_RIGHT)); @@ -325,19 +795,31 @@ void sceneHandler29_clickPorter(ExCommand *cmd) { } } -void sceneHandler29_sub05() { - warning("STUB: sceneHandler29_sub05()"); +void sceneHandler29_shootersProcess() { + if (g_fp->_aniMan->_statics->_staticsId == ST_MAN29_RUNR) { + if (g_vars->scene29_manX > 1436) { + sceneHandler29_manFromR(); + } else { + g_vars->scene29_shootDistance = (1310 - g_vars->scene29_manX) * 5213 / 100000 + 25; + + if (!g_vars->scene29_manIsHit) + g_fp->_aniMan->startAnim(MV_MAN29_RUN, 0, -1); + } + } + + g_vars->scene29_manX = g_fp->_aniMan->_ox; + g_vars->scene29_manY = g_fp->_aniMan->_oy; } void sceneHandler29_shootersEscape() { - if (g_vars->scene29_var10) { - g_vars->scene29_var20 += 2; + if (g_vars->scene29_arcadeIsOn) { + g_vars->scene29_manX += 2; - g_fp->_aniMan->setOXY(g_vars->scene29_var20, g_vars->scene29_var21); + g_fp->_aniMan->setOXY(g_vars->scene29_manX, g_vars->scene29_manY); - if (g_vars->scene29_var20 > 1310 && !g_vars->scene29_shooter1->_movement && !g_vars->scene29_shooter2->_movement + if (g_vars->scene29_manX > 1310 && !g_vars->scene29_shooter1->_movement && !g_vars->scene29_shooter2->_movement && g_vars->scene29_shooter1->_statics->_staticsId == ST_STR1_RIGHT) { - g_vars->scene29_var13 = 0; + g_vars->scene29_shootCountdown = 0; g_vars->scene29_shooter1->changeStatics2(ST_STR1_STAND); g_vars->scene29_shooter2->changeStatics2(ST_STR2_STAND); @@ -349,51 +831,123 @@ void sceneHandler29_shootersEscape() { g_fp->setObjectState(sO_LeftPipe_29, g_fp->getObjectEnumState(sO_LeftPipe_29, sO_IsOpened)); } - } else if (g_vars->scene29_var09) { - g_vars->scene29_var20 -= 4; + } else if (g_vars->scene29_manIsRiding) { + g_vars->scene29_manX -= 4; - g_fp->_aniMan->setOXY(g_vars->scene29_var20, g_vars->scene29_var21); + g_fp->_aniMan->setOXY(g_vars->scene29_manX, g_vars->scene29_manY); } } -void sceneHandler29_sub07() { - warning("STUB: sceneHandler29_sub07()"); -} - -void sceneHandler29_assHitGreen() { - if (g_vars->scene29_ass->_statics->_staticsId == ST_ASS_NORM) { - g_vars->scene29_ass->changeStatics2(ST_ASS_NORM); - g_vars->scene29_ass->startAnim(MV_ASS_HITGREEN, 0, -1); - } -} - -void sceneHandler29_assHitRed() { - if (g_vars->scene29_ass->_statics->_staticsId == ST_ASS_NORM) { - g_vars->scene29_ass->changeStatics2(ST_ASS_NORM); - g_vars->scene29_ass->startAnim(MV_ASS_HITRED, 0, -1); - } +void sceneHandler29_manRideBack() { + g_vars->scene29_manX -= 2; + + g_fp->_aniMan->setOXY(g_vars->scene29_manX, g_vars->scene29_manY); } void sceneHandler29_shoot() { - if (g_vars->scene29_var10 && g_vars->scene29_var20 < 1310) { + if (g_vars->scene29_arcadeIsOn && g_vars->scene29_manX < 1310) { if (g_fp->_rnd->getRandomNumber(1) || g_vars->scene29_shooter1->_movement || g_vars->scene29_shooter1->_statics->_staticsId != ST_STR1_RIGHT) { if (!g_vars->scene29_shooter2->_movement && g_vars->scene29_shooter2->_statics->_staticsId == ST_STR2_RIGHT) { if (g_vars->scene29_shooter2->_flags & 4) { g_vars->scene29_shooter2->startAnim(MV_STR2_SHOOT, 0, -1); - g_vars->scene29_var13 = 0; + g_vars->scene29_shootCountdown = 0; } } } else { g_vars->scene29_shooter1->startAnim(MV_STR1_SHOOT, 0, -1); - g_vars->scene29_var13 = 0; + g_vars->scene29_shootCountdown = 0; } } } void sceneHandler29_animBearded() { - warning("STUB: sceneHandler29_animBearded()"); + MessageQueue *mq; + + for (uint i = 0; i < g_vars->scene29_bearders.size(); i++) { + StaticANIObject *ani = g_vars->scene29_bearders[i]->ani; + + if (g_vars->scene29_bearders[i]->wbflag) { + int x = ani->_ox; + int y = ani->_oy; + + if (!ani->_movement && ani->_statics->_staticsId == (ST_BRDCMN_RIGHT | 0x4000)) { + x -= 4; + + if (x - g_vars->scene29_manX < 100 || !g_vars->scene29_arcadeIsOn) { + mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC29_BRDOUT1), 0, 1); + + mq->replaceKeyCode(-1, ani->_okeyCode); + mq->chain(0); + + g_vars->scene29_bearders[i]->wbflag = 0; + g_vars->scene29_bearders[i]->wbcounter = 0; + } + } + + if (!ani->_movement && ani->_statics->_staticsId == ST_BRDCMN_GOR) + ani->startAnim(MV_BRDCMN_GOR, 0, -1); + + if (ani->_movement) { + if (ani->_movement->_id == MV_BRDCMN_GOR) { + x -= 4; + + if (g_vars->scene29_manX - x < 60 || x - g_vars->scene29_manX < -260 || !g_vars->scene29_arcadeIsOn) { + ani->changeStatics2(ST_BRDCMN_RIGHT); + + mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC29_BRDOUT2), 0, 1); + + mq->replaceKeyCode(-1, ani->_okeyCode); + mq->chain(0); + + g_vars->scene29_bearders[i]->wbflag = 0; + g_vars->scene29_bearders[i]->wbcounter = 0; + } + } + } + + ani->setOXY(x, y); + continue; + } + + if (g_vars->scene29_arcadeIsOn && g_vars->scene29_bearders[i]->wbcounter > 30) { + int newx; + + if (g_fp->_rnd->getRandomNumber(1)) + goto dostuff; + + if (g_vars->scene29_manX <= 700) { + g_vars->scene29_bearders[i]->wbcounter++; + continue; + } + + if (g_vars->scene29_manX >= 1100) { + dostuff: + if (g_vars->scene29_manX <= 700 || g_vars->scene29_manX >= 1350) { + g_vars->scene29_bearders[i]->wbcounter++; + continue; + } + + mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC29_BRD2), 0, 1); + + newx = g_vars->scene29_manX - 200; + } else { + mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC29_BRD1), 0, 1); + + newx = g_vars->scene29_manX + 350; + } + + mq->getExCommandByIndex(0)->_x = newx; + mq->replaceKeyCode(-1, ani->_okeyCode); + mq->chain(0); + + g_vars->scene29_bearders[i]->wbflag = 1; + g_vars->scene29_bearders[i]->wbcounter = 0; + } + + g_vars->scene29_bearders[i]->wbcounter++; + } } @@ -408,7 +962,7 @@ int sceneHandler29(ExCommand *cmd) { break; case MSG_SC29_LAUGH: - if (g_vars->scene29_var18 == ANI_SHELL_GREEN) { + if (g_vars->scene29_hitBall == ANI_SHELL_GREEN) { g_fp->playSound(SND_29_028, 0); break; } @@ -418,9 +972,9 @@ int sceneHandler29(ExCommand *cmd) { break; case MSG_SC29_SHOWLASTRED: - if (g_vars->scene29_var05.numBalls) { - g_vars->scene29_var06.field_8->ani->show1(-1, -1, -1, 0); - g_vars->scene29_var06.field_8->ani->startAnim(MV_SHR_HITASS, 0, -1); + if (g_vars->scene29_balls.numBalls) { + g_vars->scene29_redBalls.field_8->ani->show1(-1, -1, -1, 0); + g_vars->scene29_redBalls.field_8->ani->startAnim(MV_SHR_HITASS, 0, -1); } break; @@ -434,45 +988,45 @@ int sceneHandler29(ExCommand *cmd) { break; case MSG_SC29_SHOWLASTGREEN: - if (g_vars->scene29_var05.numBalls) { - g_vars->scene29_var05.field_8->ani->show1(-1, -1, -1, 0); - g_vars->scene29_var05.field_8->ani->startAnim(MV_SHG_HITASS, 0, -1); + if (g_vars->scene29_balls.numBalls) { + g_vars->scene29_balls.field_8->ani->show1(-1, -1, -1, 0); + g_vars->scene29_balls.field_8->ani->startAnim(MV_SHG_HITASS, 0, -1); } break; case MSG_SC29_STOPRIDE: - g_vars->scene29_var09 = 0; - g_vars->scene29_var10 = 0; - g_vars->scene29_var11 = 0; - g_vars->scene29_var12 = 0; + g_vars->scene29_manIsRiding = false; + g_vars->scene29_arcadeIsOn = false; + g_vars->scene29_reachedFarRight = false; + g_vars->scene29_rideBackEnabled = false; getCurrSceneSc2MotionController()->setEnabled(); getGameLoaderInteractionController()->enableFlag24(); break; case MSG_SC29_DISABLERIDEBACK: - g_vars->scene29_var12 = 0; + g_vars->scene29_rideBackEnabled = false; break; case MSG_SC29_ENABLERIDEBACK: - g_vars->scene29_var12 = 1; - g_vars->scene29_var11 = 0; + g_vars->scene29_rideBackEnabled = true; + g_vars->scene29_reachedFarRight = false; break; case MSG_SC29_DISABLEPORTER: - g_vars->scene29_var11 = 0; + g_vars->scene29_reachedFarRight = false; break; case MSG_SC29_ENABLEPORTER: - g_vars->scene29_var11 = 1; - g_vars->scene29_var12 = 0; - g_vars->scene29_var15 = 0; + g_vars->scene29_reachedFarRight = true; + g_vars->scene29_rideBackEnabled = false; + g_vars->scene29_manIsHit = false; break; case 29: - if (!g_vars->scene29_var09 || g_vars->scene29_var10) { - if (!g_vars->scene29_var10) { + if (!g_vars->scene29_manIsRiding || g_vars->scene29_arcadeIsOn) { + if (!g_vars->scene29_arcadeIsOn) { StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(g_fp->_sceneRect.left + cmd->_x, g_fp->_sceneRect.top + cmd->_y); if (ani && ani == g_vars->scene29_porter) { @@ -492,50 +1046,50 @@ int sceneHandler29(ExCommand *cmd) { break; case 107: - if (g_vars->scene29_var10) + if (g_vars->scene29_arcadeIsOn) sceneHandler29_manBend(); break; case 33: - if (g_vars->scene29_var10) { - if (g_vars->scene29_var20 > g_fp->_sceneRect.right - 500) - g_fp->_currentScene->_x = g_fp->_sceneRect.right - g_vars->scene29_var20 - 350; + if (g_vars->scene29_arcadeIsOn) { + if (g_vars->scene29_manX > g_fp->_sceneRect.right - 500) + g_fp->_currentScene->_x = g_fp->_sceneRect.right - g_vars->scene29_manX - 350; - if (g_vars->scene29_var20 < g_fp->_sceneRect.left + 100) - g_fp->_currentScene->_x = g_vars->scene29_var20 - g_fp->_sceneRect.left - 100; + if (g_vars->scene29_manX < g_fp->_sceneRect.left + 100) + g_fp->_currentScene->_x = g_vars->scene29_manX - g_fp->_sceneRect.left - 100; } else if (g_fp->_aniMan2) { int x = g_fp->_aniMan2->_ox; - if (x < g_fp->_sceneRect.left + g_vars->scene29_var01) - g_fp->_currentScene->_x = x - g_vars->scene29_var03 - g_fp->_sceneRect.left; + if (x < g_fp->_sceneRect.left + 300) + g_fp->_currentScene->_x = x - 400 - g_fp->_sceneRect.left; - if (x > g_fp->_sceneRect.right - g_vars->scene29_var01) - g_fp->_currentScene->_x = x + g_vars->scene29_var03 - g_fp->_sceneRect.right; + if (x > g_fp->_sceneRect.right - 300) + g_fp->_currentScene->_x = x + 400 - g_fp->_sceneRect.right; } - g_vars->scene29_var20 = g_fp->_aniMan->_ox; - g_vars->scene29_var21 = g_fp->_aniMan->_oy; + g_vars->scene29_manX = g_fp->_aniMan->_ox; + g_vars->scene29_manY = g_fp->_aniMan->_oy; - sceneHandler29_sub03(); + sceneHandler29_ballHitCheck(); if (!g_vars->scene29_porter->_movement) g_vars->scene29_porter->startAnim(MV_PTR_MOVEFAST, 0, -1); - if (g_vars->scene29_var09) + if (g_vars->scene29_manIsRiding) sceneHandler29_manFromL(); - else if (g_vars->scene29_var10 && !g_fp->_aniMan->_movement) - sceneHandler29_sub05(); + else if (g_vars->scene29_arcadeIsOn && !g_fp->_aniMan->_movement) + sceneHandler29_shootersProcess(); - if (g_vars->scene29_var11) + if (g_vars->scene29_reachedFarRight) sceneHandler29_shootersEscape(); - else if (g_vars->scene29_var12) - sceneHandler29_sub07(); + else if (g_vars->scene29_rideBackEnabled) + sceneHandler29_manRideBack(); - g_vars->scene29_var13++; + g_vars->scene29_shootCountdown++; - if (g_vars->scene29_var13 > g_vars->scene29_var14) + if (g_vars->scene29_shootCountdown > g_vars->scene29_shootDistance) sceneHandler29_shoot(); sceneHandler29_animBearded(); @@ -552,10 +1106,10 @@ int sceneHandler29(ExCommand *cmd) { int scene29_updateCursor() { g_fp->updateCursorCommon(); - if (g_vars->scene29_var10) { + if (g_vars->scene29_arcadeIsOn) { if (g_fp->_cursorId != PIC_CSR_DEFAULT_INV && g_fp->_cursorId != PIC_CSR_ITN_INV) g_fp->_cursorId = -1; - } else if (g_vars->scene29_var09) { + } else if (g_vars->scene29_manIsRiding) { if (g_fp->_cursorId != PIC_CSR_DEFAULT_INV && g_fp->_cursorId != PIC_CSR_ITN_INV) g_fp->_cursorId = PIC_CSR_DEFAULT; } else if (g_fp->_objectIdAtCursor == ANI_PORTER) { diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp index bb6aabd2b5..aa91f25087 100644 --- a/engines/fullpipe/sound.cpp +++ b/engines/fullpipe/sound.cpp @@ -119,6 +119,10 @@ void Sound::setPanAndVolumeByStaticAni() { debug(3, "STUB Sound::setPanAndVolumeByStaticAni()"); } +void Sound::setPanAndVolume(int vol, int pan) { + warning("STUB: Sound::setPanAndVolume"); +} + void FullpipeEngine::setSceneMusicParameters(GameVar *var) { warning("STUB: FullpipeEngine::setSceneMusicParameters()"); // TODO: Finish this (MINDELAY, MAXDELAY, LOCAL, SEQUENCE, STARTDELAY etc) @@ -203,4 +207,10 @@ void FullpipeEngine::updateSoundVolume() { debug(3, "STUB FullpipeEngine::updateSoundVolume()"); } +void FullpipeEngine::setMusicVolume(int vol) { + _musicVolume = vol; + + debug(3, "STUB FullpipeEngine::setMusicVolume()"); +} + } // End of namespace Fullpipe diff --git a/engines/fullpipe/sound.h b/engines/fullpipe/sound.h index 8ddfc753ce..e284e5efab 100644 --- a/engines/fullpipe/sound.h +++ b/engines/fullpipe/sound.h @@ -28,13 +28,15 @@ namespace Fullpipe { class Sound : public MemoryObject { int _id; char *_description; - int16 _objectId; int _directSoundBuffer; int _directSoundBuffers[7]; byte *_soundData; Audio::SoundHandle _handle; public: + int16 _objectId; + +public: Sound(); virtual ~Sound(); @@ -45,6 +47,7 @@ public: Audio::SoundHandle getHandle() const { return _handle; } void setPanAndVolumeByStaticAni(); + void setPanAndVolume(int vol, int pan); }; class SoundList : public CObject { 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/groovie/roq.cpp b/engines/groovie/roq.cpp index cbaa992596..2776a0455d 100644 --- a/engines/groovie/roq.cpp +++ b/engines/groovie/roq.cpp @@ -43,8 +43,9 @@ namespace Groovie { -ROQPlayer::ROQPlayer(GroovieEngine *vm) : VideoPlayer(vm), _codingTypeCount(0), _bg(&_vm->_graphicsMan->_background) { - // _fg = &_vm->_graphicsMan->_foreground; +ROQPlayer::ROQPlayer(GroovieEngine *vm) : + VideoPlayer(vm), _codingTypeCount(0), + _bg(&_vm->_graphicsMan->_background) { // Create the work surfaces _currBuf = new Graphics::Surface(); diff --git a/engines/groovie/roq.h b/engines/groovie/roq.h index b5e63c2b4a..cd5e91c82b 100644 --- a/engines/groovie/roq.h +++ b/engines/groovie/roq.h @@ -75,7 +75,6 @@ private: byte _codebook4[256 * 4]; // Buffers - // Graphics::Surface *_fg, *_thirdBuf; Graphics::Surface *_bg; Graphics::Surface *_currBuf, *_prevBuf; void buildShowBuf(); diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp index 10cbc49c7c..725dedae3f 100644 --- a/engines/kyra/sound_towns.cpp +++ b/engines/kyra/sound_towns.cpp @@ -538,7 +538,8 @@ bool SoundTownsPC98_v2::init() { // check if we have access to CD audio. Resource *r = _vm->resource(); if (_musicEnabled && - (r->exists("track1.mp3") || r->exists("track1.ogg") || r->exists("track1.flac") || r->exists("track1.fla"))) + (r->exists("track1.mp3") || r->exists("track1.ogg") || r->exists("track1.flac") || r->exists("track1.fla") + || r->exists("track01.mp3") || r->exists("track01.ogg") || r->exists("track01.flac") || r->exists("track01.fla"))) _musicEnabled = 2; else _musicEnabled = 1; diff --git a/engines/lastexpress/data/animation.cpp b/engines/lastexpress/data/animation.cpp index 9c8cc202aa..148854e04d 100644 --- a/engines/lastexpress/data/animation.cpp +++ b/engines/lastexpress/data/animation.cpp @@ -39,7 +39,7 @@ namespace LastExpress { -Animation::Animation() : _stream(NULL), _currentChunk(NULL), _overlay(NULL), _background1(NULL), _background2(NULL), _backgroundCurrent(0), _audio(NULL), _startTime(0), _changed(false), _flag(0) { +Animation::Animation() : _stream(NULL), _currentChunk(NULL), _overlay(NULL), _background1(NULL), _background2(NULL), _backgroundCurrent(0), _audio(NULL), _startTime(0), _changed(false) { } Animation::~Animation() { diff --git a/engines/lastexpress/data/animation.h b/engines/lastexpress/data/animation.h index 7f6922866a..9523cddb78 100644 --- a/engines/lastexpress/data/animation.h +++ b/engines/lastexpress/data/animation.h @@ -113,7 +113,6 @@ private: uint32 _startTime; bool _changed; - int _flag; }; } // End of namespace LastExpress diff --git a/engines/lastexpress/data/sequence.cpp b/engines/lastexpress/data/sequence.cpp index c7073b560c..f43e2afdef 100644 --- a/engines/lastexpress/data/sequence.cpp +++ b/engines/lastexpress/data/sequence.cpp @@ -76,7 +76,7 @@ void FrameInfo::read(Common::SeekableReadStream *in, bool isSequence) { // AnimFrame -AnimFrame::AnimFrame(Common::SeekableReadStream *in, const FrameInfo &f, bool ignoreSubtype) : _palette(NULL), _ignoreSubtype(ignoreSubtype) { +AnimFrame::AnimFrame(Common::SeekableReadStream *in, const FrameInfo &f, bool /* ignoreSubtype */) : _palette(NULL) { _palSize = 1; // TODO: use just the needed rectangle _image.create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); diff --git a/engines/lastexpress/data/sequence.h b/engines/lastexpress/data/sequence.h index dbb08a0c07..fd8b3cd27b 100644 --- a/engines/lastexpress/data/sequence.h +++ b/engines/lastexpress/data/sequence.h @@ -147,7 +147,6 @@ private: uint16 _palSize; uint16 *_palette; Common::Rect _rect; - bool _ignoreSubtype; }; class Sequence { 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/parallaction/saveload.h b/engines/parallaction/saveload.h index dbbbb42066..c9b724e69d 100644 --- a/engines/parallaction/saveload.h +++ b/engines/parallaction/saveload.h @@ -71,12 +71,12 @@ public: }; class SaveLoad_br : public SaveLoad { - Parallaction_br *_vm; +// Parallaction_br *_vm; virtual void doLoadGame(uint16 slot); virtual void doSaveGame(uint16 slot, const char* name); public: - SaveLoad_br(Parallaction_br *vm, Common::SaveFileManager *saveFileMan) : SaveLoad(saveFileMan, "bra"), _vm(vm) { } + SaveLoad_br(Parallaction_br *vm, Common::SaveFileManager *saveFileMan) : SaveLoad(saveFileMan, "bra") { } virtual void getGamePartProgress(bool *complete, int size); virtual void setPartComplete(const char *part); diff --git a/engines/pegasus/ai/ai_area.cpp b/engines/pegasus/ai/ai_area.cpp index 5ac8af8812..9cab568d66 100644 --- a/engines/pegasus/ai/ai_area.cpp +++ b/engines/pegasus/ai/ai_area.cpp @@ -234,6 +234,7 @@ void AIArea::playAIAreaSequence(const LowerClientSignature, const LowerAreaSigna vm->_cursor->hide(); while (_middleAreaMovie.isRunning()) { + InputDevice.pumpEvents(); vm->checkCallBacks(); vm->refreshDisplay(); g_system->delayMillis(10); @@ -258,6 +259,7 @@ void AIArea::playAIAreaSequence(const LowerClientSignature, const LowerAreaSigna vm->_cursor->hide(); while (_rightAreaMovie.isRunning()) { + InputDevice.pumpEvents(); vm->checkCallBacks(); vm->refreshDisplay(); g_system->delayMillis(10); diff --git a/engines/pegasus/energymonitor.cpp b/engines/pegasus/energymonitor.cpp index be9d205360..40e54afb89 100644 --- a/engines/pegasus/energymonitor.cpp +++ b/engines/pegasus/energymonitor.cpp @@ -269,6 +269,7 @@ void EnergyMonitor::calibrateEnergyBar() { // Make sure warning light is hidden... _energyLight.hide(); while (getCurrentEnergy() != (int32)kMaxJMPEnergy) { + InputDevice.pumpEvents(); vm->checkCallBacks(); vm->refreshDisplay(); g_system->delayMillis(10); diff --git a/engines/pegasus/fader.cpp b/engines/pegasus/fader.cpp index a2bbf22944..80ce8ef5dc 100644 --- a/engines/pegasus/fader.cpp +++ b/engines/pegasus/fader.cpp @@ -94,6 +94,7 @@ void Fader::startFaderSync(const FaderMoveSpec &spec) { start(); while (isFading()) { + InputDevice.pumpEvents(); ((PegasusEngine *)g_engine)->checkCallBacks(); useIdleTime(); } diff --git a/engines/pegasus/input.cpp b/engines/pegasus/input.cpp index b74e4a4c45..283d55421f 100644 --- a/engines/pegasus/input.cpp +++ b/engines/pegasus/input.cpp @@ -81,9 +81,7 @@ void InputDeviceManager::getInput(Input &input, const InputBits filter) { // (ie. if one uses enter to access the restore menu, we never receive // the key up event, which leads to bad things) // This is to closely emulate what the GetKeys() function did on Mac OS - Common::Event event; - while (g_system->getEventManager()->pollEvent(event)) - ; + pumpEvents(); // Now create the bitfield InputBits currentBits = 0; @@ -206,6 +204,13 @@ bool InputDeviceManager::notifyEvent(const Common::Event &event) { return false; } +void InputDeviceManager::pumpEvents() { + // Just poll for events. notifyEvent() will pick up on them. + Common::Event event; + while (g_system->getEventManager()->pollEvent(event)) + ; +} + int operator==(const Input &arg1, const Input &arg2) { return arg1._inputState == arg2._inputState; } diff --git a/engines/pegasus/input.h b/engines/pegasus/input.h index 3e938fa42a..ba6f11dba0 100644 --- a/engines/pegasus/input.h +++ b/engines/pegasus/input.h @@ -50,6 +50,8 @@ public: void waitInput(const InputBits); + void pumpEvents(); + protected: friend class Common::Singleton<SingletonBaseType>; diff --git a/engines/pegasus/interface.cpp b/engines/pegasus/interface.cpp index f2429bf36a..f8ae6a0752 100644 --- a/engines/pegasus/interface.cpp +++ b/engines/pegasus/interface.cpp @@ -604,6 +604,7 @@ void Interface::raiseInventoryDrawerSync() { raiseInventoryDrawer(false); while (_inventoryLid.isRunning()) { + InputDevice.pumpEvents(); vm->checkCallBacks(); vm->refreshDisplay(); g_system->delayMillis(10); @@ -613,6 +614,7 @@ void Interface::raiseInventoryDrawerSync() { inventoryLidOpen(false); while (_inventoryPush.isFading()) { + InputDevice.pumpEvents(); vm->checkCallBacks(); vm->refreshDisplay(); g_system->delayMillis(10); @@ -628,6 +630,7 @@ void Interface::lowerInventoryDrawerSync() { lowerInventoryDrawer(false); while (_inventoryPush.isFading()) { + InputDevice.pumpEvents(); vm->checkCallBacks(); vm->refreshDisplay(); g_system->delayMillis(10); @@ -637,6 +640,7 @@ void Interface::lowerInventoryDrawerSync() { inventoryDrawerDown(false); while (_inventoryLid.isRunning()) { + InputDevice.pumpEvents(); vm->checkCallBacks(); vm->refreshDisplay(); g_system->delayMillis(10); @@ -652,6 +656,7 @@ void Interface::raiseBiochipDrawerSync() { raiseBiochipDrawer(false); while (_biochipLid.isRunning()) { + InputDevice.pumpEvents(); vm->checkCallBacks(); vm->refreshDisplay(); g_system->delayMillis(10); @@ -661,6 +666,7 @@ void Interface::raiseBiochipDrawerSync() { biochipLidOpen(false); while (_biochipPush.isFading()) { + InputDevice.pumpEvents(); vm->checkCallBacks(); vm->refreshDisplay(); g_system->delayMillis(10); @@ -676,6 +682,7 @@ void Interface::lowerBiochipDrawerSync() { lowerBiochipDrawer(false); while (_biochipPush.isFading()) { + InputDevice.pumpEvents(); vm->checkCallBacks(); vm->refreshDisplay(); g_system->delayMillis(10); @@ -685,6 +692,7 @@ void Interface::lowerBiochipDrawerSync() { biochipDrawerDown(false); while (_biochipLid.isRunning()) { + InputDevice.pumpEvents(); vm->checkCallBacks(); vm->refreshDisplay(); g_system->delayMillis(10); diff --git a/engines/pegasus/items/inventorypicture.cpp b/engines/pegasus/items/inventorypicture.cpp index fc812faae2..bfdc382f5d 100644 --- a/engines/pegasus/items/inventorypicture.cpp +++ b/engines/pegasus/items/inventorypicture.cpp @@ -331,6 +331,7 @@ void InventoryItemsPicture::playEndMessage(DisplayElement *pushElement) { endMessage.start(); while (endMessage.isRunning()) { + InputDevice.pumpEvents(); vm->checkCallBacks(); vm->refreshDisplay(); g_system->delayMillis(10); 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..f7493dbe75 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()) { @@ -2476,6 +2480,7 @@ void Mars::doCanyonChase() { _shuttleEnergyMeter.initShuttleEnergyMeter(); _shuttleEnergyMeter.powerUpMeter(); while (_shuttleEnergyMeter.isFading()) { + InputDevice.pumpEvents(); _vm->checkCallBacks(); _vm->refreshDisplay(); g_system->updateScreen(); @@ -2812,6 +2817,7 @@ void Mars::marsTimerExpired(MarsTimerEvent &event) { GameState.setScoringEnteredLaunchTube(); while (_canyonChaseMovie.isRunning()) { + InputDevice.pumpEvents(); _vm->checkCallBacks(); _vm->refreshDisplay(); _vm->_system->delayMillis(10); @@ -2945,6 +2951,7 @@ void Mars::marsTimerExpired(MarsTimerEvent &event) { showBigExplosion(r, kShuttleAlienShipOrder); while (_explosions.isRunning()) { + InputDevice.pumpEvents(); _vm->checkCallBacks(); _vm->refreshDisplay(); g_system->delayMillis(10); @@ -3138,6 +3145,7 @@ void Mars::spaceChaseClick(const Input &input, const HotSpotID id) { _shuttleEnergyMeter.drainForTractorBeam(); while (_shuttleEnergyMeter.isFading()) { + InputDevice.pumpEvents(); _vm->checkCallBacks(); _vm->refreshDisplay(); _vm->_system->delayMillis(10); @@ -3172,6 +3180,7 @@ void Mars::spaceChaseClick(const Input &input, const HotSpotID id) { // wait here until any junk clears... while (_junk.junkFlying()) { + InputDevice.pumpEvents(); _vm->checkCallBacks(); _vm->refreshDisplay(); _vm->_system->delayMillis(10); diff --git a/engines/pegasus/neighborhood/neighborhood.cpp b/engines/pegasus/neighborhood/neighborhood.cpp index 3116bd7978..320fbdabaa 100644 --- a/engines/pegasus/neighborhood/neighborhood.cpp +++ b/engines/pegasus/neighborhood/neighborhood.cpp @@ -470,6 +470,7 @@ void Neighborhood::requestSpotSound(const TimeValue in, const TimeValue out, con void Neighborhood::playSpotSoundSync(const TimeValue in, const TimeValue out) { // Let the action queue play out first... while (!actionQueueEmpty()) { + InputDevice.pumpEvents(); _vm->checkCallBacks(); _vm->refreshDisplay(); _vm->checkNotifications(); @@ -480,6 +481,7 @@ void Neighborhood::playSpotSoundSync(const TimeValue in, const TimeValue out) { _spotSounds.playSoundSegment(in, out); while (_spotSounds.isPlaying()) { + InputDevice.pumpEvents(); _vm->checkCallBacks(); _vm->refreshDisplay(); _vm->_system->delayMillis(10); @@ -1105,6 +1107,7 @@ void Neighborhood::startTurnPush(const TurnDirection turnDirection, const TimeVa _turnPush.continueFader(); do { + InputDevice.pumpEvents(); _vm->checkCallBacks(); _vm->refreshDisplay(); _vm->_system->delayMillis(10); @@ -1616,6 +1619,7 @@ void Neighborhood::playMovieSegment(Movie *movie, TimeValue startTime, TimeValue movie->start(); while (movie->isRunning()) { + InputDevice.pumpEvents(); _vm->checkCallBacks(); _vm->refreshDisplay(); _vm->_system->delayMillis(10); diff --git a/engines/pegasus/neighborhood/tsa/fulltsa.cpp b/engines/pegasus/neighborhood/tsa/fulltsa.cpp index 75f652ad56..92b79c038e 100644 --- a/engines/pegasus/neighborhood/tsa/fulltsa.cpp +++ b/engines/pegasus/neighborhood/tsa/fulltsa.cpp @@ -1692,7 +1692,9 @@ void FullTSA::initializeTBPMonitor(const int newMode, const ExtraID highlightExt releaseSprites(); } - _interruptionFilter = kFilterAllInput; + // Only allow input if we're not in the middle of series of queue requests. + if (actionQueueEmpty()) + _interruptionFilter = kFilterAllInput; } void FullTSA::startUpComparisonMonitor() { @@ -2643,6 +2645,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/neighborhood/wsc/wsc.cpp b/engines/pegasus/neighborhood/wsc/wsc.cpp index 09e2a48a52..f009b35cdc 100644 --- a/engines/pegasus/neighborhood/wsc/wsc.cpp +++ b/engines/pegasus/neighborhood/wsc/wsc.cpp @@ -2029,6 +2029,7 @@ void WSC::moleculeGameClick(const HotSpotID id) { _moleculesMovie.start(); while (_moleculesMovie.isRunning()) { + InputDevice.pumpEvents(); _vm->checkCallBacks(); _vm->refreshDisplay(); _vm->_system->delayMillis(10); @@ -2063,6 +2064,7 @@ void WSC::moleculeGameClick(const HotSpotID id) { _moleculesMovie.start(); while (_moleculesMovie.isRunning()) { + InputDevice.pumpEvents(); _vm->checkCallBacks(); _vm->refreshDisplay(); _vm->_system->delayMillis(10); @@ -2076,6 +2078,7 @@ void WSC::moleculeGameClick(const HotSpotID id) { while (_moleculesMovie.isRunning()) { + InputDevice.pumpEvents(); _vm->checkCallBacks(); _vm->refreshDisplay(); _vm->_system->delayMillis(10); diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp index c5edd34a01..a0ec12a7c4 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; } @@ -834,6 +836,7 @@ void PegasusEngine::delayShell(TimeValue time, TimeScale scale) { uint32 timeInMillis = time * 1000 / scale; while (g_system->getMillis() < startTime + timeInMillis) { + InputDevice.pumpEvents(); checkCallBacks(); _gfx->updateDisplay(); } @@ -969,8 +972,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 +1030,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 +1683,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); @@ -2159,6 +2176,7 @@ void PegasusEngine::autoDragItemIntoRoom(Item *item, Sprite *draggingSprite) { _autoDragger.autoDrag(draggingSprite, start, stop, time, kDefaultTimeScale); while (_autoDragger.isDragging()) { + InputDevice.pumpEvents(); checkCallBacks(); refreshDisplay(); _system->delayMillis(10); @@ -2192,6 +2210,7 @@ void PegasusEngine::autoDragItemIntoInventory(Item *, Sprite *draggingSprite) { _autoDragger.autoDrag(draggingSprite, start, stop, time, kDefaultTimeScale); while (_autoDragger.isDragging()) { + InputDevice.pumpEvents(); checkCallBacks(); refreshDisplay(); _system->delayMillis(10); @@ -2268,10 +2287,7 @@ void PegasusEngine::doSubChase() { drawScaledFrame(frame, 0, 0); } - Common::Event event; - while (_eventMan->pollEvent(event)) - ; - + InputDevice.pumpEvents(); _system->delayMillis(10); } 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/queen/debug.cpp b/engines/queen/debug.cpp index 96fa81488f..3706806ac2 100644 --- a/engines/queen/debug.cpp +++ b/engines/queen/debug.cpp @@ -21,6 +21,7 @@ */ #include "common/scummsys.h" +#include "common/util.h" #include "queen/debug.h" @@ -57,8 +58,17 @@ void Debugger::postEnter() { _vm->graphics()->setupMouseCursor(); } +static bool isNumeric(const char *arg) { + const char *str = arg; + bool retVal = true; + while (retVal && (*str != '\0')) { + retVal = Common::isDigit(*str++); + } + return retVal; +} + bool Debugger::Cmd_Asm(int argc, const char **argv) { - if (argc == 2) { + if (argc == 2 && isNumeric(argv[1])) { uint16 sm = atoi(argv[1]); _vm->logic()->executeSpecialMove(sm); return false; @@ -75,12 +85,17 @@ bool Debugger::Cmd_Areas(int argc, const char **argv) { } bool Debugger::Cmd_Bob(int argc, const char **argv) { - if (argc >= 3) { + if (argc >= 3 && isNumeric(argv[1])) { int bobNum = atoi(argv[1]); if (bobNum >= Graphics::MAX_BOBS_NUMBER) { DebugPrintf("Bob %d is out of range (range: 0 - %d)\n", bobNum, Graphics::MAX_BOBS_NUMBER); } else { - int param = (argc > 3) ? atoi(argv[3]) : 0; + int param = 0; + if (argc > 3 && isNumeric(argv[3])) { + param = atoi(argv[3]); + } else { + DebugPrintf("Invalid parameter for bob command '%s'\n", argv[2]); + } BobSlot *bob = _vm->graphics()->bob(bobNum); if (!strcmp(argv[2], "toggle")) { bob->active = !bob->active; @@ -109,22 +124,21 @@ bool Debugger::Cmd_Bob(int argc, const char **argv) { bool Debugger::Cmd_GameState(int argc, const char **argv) { uint16 slot; - switch (argc) { - case 2: - slot = atoi(argv[1]); - DebugPrintf("GAMESTATE[%d] ", slot); - DebugPrintf("is %d\n", _vm->logic()->gameState(slot)); - break; - case 3: + if ((argc == 2 || argc == 3) && isNumeric(argv[1])) { slot = atoi(argv[1]); DebugPrintf("GAMESTATE[%d] ", slot); - DebugPrintf("was %d ", _vm->logic()->gameState(slot)); - _vm->logic()->gameState(slot, atoi(argv[2])); - DebugPrintf("now %d\n", _vm->logic()->gameState(slot)); - break; - default: - DebugPrintf("Usage: %s slotnum value\n", argv[0]); - break; + DebugPrintf("%s %d\n", (argc == 2) ? "is" : "was", _vm->logic()->gameState(slot)); + + if (argc == 3) { + if (isNumeric(argv[1])) { + _vm->logic()->gameState(slot, atoi(argv[2])); + DebugPrintf("now %d\n", _vm->logic()->gameState(slot)); + } else { + DebugPrintf("Usage: %s slotnum <value>\n", argv[0]); + } + } + } else { + DebugPrintf("Usage: %s slotnum <value>\n", argv[0]); } return true; } @@ -164,7 +178,7 @@ bool Debugger::Cmd_PrintBobs(int argc, const char**argv) { } bool Debugger::Cmd_Room(int argc, const char **argv) { - if (argc == 2) { + if (argc == 2 && isNumeric(argv[1])) { uint16 roomNum = atoi(argv[1]); _vm->logic()->joePos(0, 0); _vm->logic()->newRoom(roomNum); @@ -180,7 +194,7 @@ bool Debugger::Cmd_Room(int argc, const char **argv) { } bool Debugger::Cmd_Song(int argc, const char **argv) { - if (argc == 2) { + if (argc == 2 && isNumeric(argv[1])) { int16 songNum = atoi(argv[1]); _vm->sound()->playSong(songNum); DebugPrintf("Playing song %d\n", songNum); diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index a405ee5c7c..b4d245197b 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -2668,8 +2668,8 @@ void ScriptPatcher::initSignature(const SciScriptPatcherEntry *patchTable, bool uint16 curWord; uint16 curCommand; uint32 curValue; - byte byte1; - byte byte2; + byte byte1 = 0; + byte byte2 = 0; int patchEntryCount = 0; // Count entries and allocate runtime data diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index bb1a7ffaf1..1d1b6b4f13 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -380,7 +380,7 @@ void ScummEngine::initVirtScreen(VirtScreenNumber slot, int top, int width, int int size; assert(height >= 0); - assert(slot >= 0 && slot < 4); + assert((int)slot >= 0 && (int)slot < 4); if (_game.version >= 7) { if (slot == kMainVirtScreen && (_roomHeight != 0)) diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 8d278f6ddf..0aaff4c094 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -1242,7 +1242,9 @@ void ScummEngine::saveOrLoad(Serializer *s) { } s->saveUint16(0xFFFF); // End marker } else { - while ((type = (ResType)s->loadUint16()) != 0xFFFF) { + uint16 tmp; + while ((tmp = s->loadUint16()) != 0xFFFF) { + type = (ResType)tmp; while ((idx = s->loadUint16()) != 0xFFFF) { assert(idx < _res->_types[type].size()); loadResource(s, type, idx); @@ -1430,7 +1432,9 @@ void ScummEngine::saveOrLoad(Serializer *s) { } s->saveByte(0xFF); } else { - while ((type = (ResType)s->loadByte()) != 0xFF) { + uint8 tmp; + while ((tmp = s->loadByte()) != 0xFF) { + type = (ResType)tmp; idx = s->loadUint16(); _res->lock(type, idx); } diff --git a/engines/sky/debug.cpp b/engines/sky/debug.cpp index a417bc2ece..63da42eec2 100644 --- a/engines/sky/debug.cpp +++ b/engines/sky/debug.cpp @@ -1108,6 +1108,15 @@ void Debugger::postEnter() { _mouse->resetCursor(); } +static bool isNumeric(const char *arg) { + const char *str = arg; + bool retVal = true; + while (retVal && (*str != '\0')) { + retVal = Common::isDigit(*str++); + } + return retVal; +} + bool Debugger::Cmd_ShowGrid(int argc, const char **argv) { _showGrid = !_showGrid; DebugPrintf("Show grid: %s\n", _showGrid ? "On" : "Off"); @@ -1299,22 +1308,20 @@ bool Debugger::Cmd_ScriptVar(int argc, const char **argv) { } bool Debugger::Cmd_Section(int argc, const char **argv) { - if (argc < 2) { - DebugPrintf("Example: %s 4\n", argv[0]); - return true; - } - - const int baseId[] = { START_ONE, START_S6, START_29, START_SC31, START_SC66, START_SC90, START_SC81 }; - int section = atoi(argv[1]); + if (argc == 2 && isNumeric(argv[1])) { + const int baseId[] = { START_ONE, START_S6, START_29, START_SC31, START_SC66, START_SC90, START_SC81 }; + int section = atoi(argv[1]); - if (section >= 0 && section <= 6) { - _logic->fnEnterSection(section == 6 ? 4 : section, 0, 0); - _logic->fnAssignBase(ID_FOSTER, baseId[section], 0); - _skyCompact->fetchCpt(ID_FOSTER)->megaSet = 0; + if (section >= 0 && section <= 6) { + _logic->fnEnterSection(section == 6 ? 4 : section, 0, 0); + _logic->fnAssignBase(ID_FOSTER, baseId[section], 0); + _skyCompact->fetchCpt(ID_FOSTER)->megaSet = 0; + } else { + DebugPrintf("Section %d is out of range (range: %d - %d)\n", section, 0, 6); + } } else { - DebugPrintf("Unknown section '%s'\n", argv[1]); + DebugPrintf("Example: %s 4\n", argv[0]); } - return true; } diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.cpp b/engines/tsage/ringworld2/ringworld2_scenes3.cpp index 95f8c85efe..3f32503fdf 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes3.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes3.cpp @@ -5048,6 +5048,7 @@ void Scene3700::signal() { Scene3800::Scene3800() { _desertDirection = 0; + _skylineRect.set(0, 0, 320, 87); } void Scene3800::synchronize(Serializer &s) { @@ -5220,7 +5221,8 @@ void Scene3800::initExits() { } void Scene3800::enterArea() { - R2_GLOBALS._player.disableControl(); + R2_GLOBALS._player.disableControl(CURSOR_WALK); + switch (_desertDirection) { case 0: R2_GLOBALS._player.postInit(); @@ -5346,7 +5348,6 @@ void Scene3800::postInit(SceneObjectList *OwnerList) { _westExit.setDetails(Rect(0, 87, 14, 168), EXITCURSOR_W, 3800); _westExit.setDest(Common::Point(7, 145)); - _skylineRect.set(0, 0, 320, 87); _background.setDetails(Rect(0, 0, 320, 200), 3800, 0, 1, 2, 1, (SceneItem *) NULL); enterArea(); 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/detection.cpp b/engines/wintermute/detection.cpp index 48c75f634d..a659c434d0 100644 --- a/engines/wintermute/detection.cpp +++ b/engines/wintermute/detection.cpp @@ -107,11 +107,11 @@ public: } } // Prefix to avoid collisions with actually known games - name = "wmefan-" + name; + name = "wmeunk-" + name; Common::strlcpy(s_fallbackGameIdBuf, name.c_str(), sizeof(s_fallbackGameIdBuf) - 1); s_fallbackDesc.gameid = s_fallbackGameIdBuf; if (caption != name) { - caption += " (fangame) "; + caption += " (unknown version) "; char *offset = s_fallbackGameIdBuf + name.size() + 1; uint32 remainingLength = (sizeof(s_fallbackGameIdBuf) - 1) - (name.size() + 1); Common::strlcpy(offset, caption.c_str(), remainingLength); diff --git a/engines/wintermute/detection_tables.h b/engines/wintermute/detection_tables.h index 0bf9fff4f3..6556d3b34a 100644 --- a/engines/wintermute/detection_tables.h +++ b/engines/wintermute/detection_tables.h @@ -38,6 +38,7 @@ static const PlainGameDescriptor wintermuteGames[] = { {"carolreed8", "Carol Reed 8 - Amber's Blood"}, {"carolreed9", "Carol Reed 9 - Cold Case Summer"}, {"chivalry", "Chivalry is Not Dead"}, + {"corrosion", "Corrosion: Cold Winter Waiting"}, {"deadcity", "Dead City"}, {"dreaming", "Des Reves Elastiques Avec Mille Insectes Nommes Georges"}, {"dirtysplit", "Dirty Split"}, @@ -58,6 +59,8 @@ static const PlainGameDescriptor wintermuteGames[] = { {"projectdoom", "Project: Doom"}, {"reversion1", "Reversion: The Escape"}, {"reversion2", "Reversion: The Meeting"}, + {"rhiannon", "Rhiannon: Curse of the four Branches"}, + {"ritter", "1 1/2 Ritter: Auf der Suche nach der hinreissenden Herzelinde"}, {"rosemary", "Rosemary"}, {"securanote", "Securanote"}, {"shaban", "Shaban"}, @@ -125,6 +128,16 @@ static const ADGameDescription gameDescriptions[] = { ADGF_UNSTABLE, GUIO0() }, + // Bickadoodle (download from http://aethericgames.com/games/bickadoodle/download-bickadoodle/) + { + "bickadoodle", + "", + AD_ENTRY1s("data.dcp", "1584d83577c32add0fce27fae91141a2", 35337728), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, // Book of Gron Part One { "bookofgron", @@ -238,6 +251,16 @@ static const ADGameDescription gameDescriptions[] = { ADGF_TESTING, GUIO0() }, + // Corrosion: Cold Winter Waiting + { + "corrosion", + "", + AD_ENTRY1s("data.dcp", "ae885b1a8faa0b27f43c0e8f0df02fc9", 525931618), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_TESTING, + GUIO0() + }, // Dead City (Czech) { "deadcity", @@ -429,7 +452,21 @@ static const ADGameDescription gameDescriptions[] = { ADGF_UNSTABLE, GUIO0() }, - // Ghosts in the Sheet + // Ghost in the Sheet + { + "ghostsheet", + "", + { + {"english.dcp", 0, "e6d0aad2c89996bcabe416105a3d6d3a", 12221017}, + {"data.dcp", 0, "b2f8b05328e4881e15e98e845b63f451", 168003}, + AD_LISTEND + }, + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, + // Ghost in the Sheet (Demo) { "ghostsheet", "Demo", @@ -531,6 +568,16 @@ static const ADGameDescription gameDescriptions[] = { ADGF_UNSTABLE, GUIO0() }, + // J.U.L.I.A. (English, Bundle in a box-version) + { + "julia", + "Version 1.2", + AD_ENTRY1s("data.dcp", "fe90023ccc22f35185b40b910e0d03a2", 10101373), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, // J.U.L.I.A. (English) (Demo) { "julia", @@ -997,6 +1044,56 @@ static const ADGameDescription gameDescriptions[] = { ADGF_UNSTABLE, GUIO0() }, + // Reversion: The Meeting Version 2.0.2412 (Chinese) + { + "reversion2", + "Version 2.0.2412", + { + {"data.dcp", 0, "f4ffc4df24b7bebad56a24930f33a2bc", 255766600}, + {"xlanguage_nz.dcp", 0, "17c79af4928e24484bee77a7e807cc2a", 10737127}, + {"Linux.dcp", 0, "21858bd77dc86b03f701fd47900e2f51", 984535}, + AD_LISTEND + }, + Common::ZH_CNA, + Common::kPlatformLinux, + ADGF_UNSTABLE, + GUIO0() + }, + // Reversion: The Meeting Version 2.0.2412 (English) + { + "reversion2", + "Version 2.0.2412", + { + {"data.dcp", 0, "f4ffc4df24b7bebad56a24930f33a2bc", 255766600}, + {"xlanguage_en.dcp", 0, "0598bf752ce93b42bcaf1094df537c7b", 8533057}, + {"Linux.dcp", 0, "21858bd77dc86b03f701fd47900e2f51", 984535}, + AD_LISTEND + }, + Common::EN_ANY, + Common::kPlatformLinux, + ADGF_UNSTABLE, + GUIO0() + }, + // Rhiannon: Curse of the four Branches + { + "rhiannon", + "", + AD_ENTRY1s("data.dcp", "870f348900b735f1cc79c0608ce32b0e", 1046169851), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, + // 1 1/2 Ritter: Auf der Suche nach der hinreissenden Herzelinde + { + "ritter", + "", + AD_ENTRY1s("data.dcp", "5ac416cee605d3a30f4d59687b1cdab2", 364260278), + Common::DE_DEU, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, // Rosemary { "rosemary", 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); diff --git a/engines/zvision/fonts/truetype_font.cpp b/engines/zvision/fonts/truetype_font.cpp index 03520f18b6..ba4d72bde8 100644 --- a/engines/zvision/fonts/truetype_font.cpp +++ b/engines/zvision/fonts/truetype_font.cpp @@ -39,12 +39,9 @@ namespace ZVision { TruetypeFont::TruetypeFont(ZVision *engine, int32 fontHeight) - : _engine(engine), - _fontHeight(fontHeight), + : _fontHeight(fontHeight), _font(0), - _lineHeight(0), - _maxCharWidth(0), - _maxCharHeight(0) { + _lineHeight(0) { } TruetypeFont::~TruetypeFont(void) { diff --git a/engines/zvision/fonts/truetype_font.h b/engines/zvision/fonts/truetype_font.h index 3b5805db14..64f53a2c3b 100644 --- a/engines/zvision/fonts/truetype_font.h +++ b/engines/zvision/fonts/truetype_font.h @@ -43,12 +43,12 @@ public: ~TruetypeFont(); private: - ZVision *_engine; +// ZVision *_engine; Graphics::Font *_font; int _lineHeight; - size_t _maxCharWidth; - size_t _maxCharHeight; +// size_t _maxCharWidth; +// size_t _maxCharHeight; public: int32 _fontHeight; |