scummvm/engines/access/amazon/amazon_scripts.cpp
2015-12-11 22:42:18 -05:00

536 lines
13 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/scummsys.h"
#include "access/access.h"
#include "access/resources.h"
#include "access/amazon/amazon_game.h"
#include "access/amazon/amazon_resources.h"
#include "access/amazon/amazon_scripts.h"
namespace Access {
namespace Amazon {
AmazonScripts::AmazonScripts(AccessEngine *vm) : Scripts(vm) {
_game = (AmazonEngine *)_vm;
setOpcodes_v2();
}
void AmazonScripts::cLoop() {
searchForSequence();
_vm->_images.clear();
_vm->_buffer2.blitFrom(_vm->_buffer1);
_vm->_oldRects.clear();
_vm->_scripts->executeScript();
_vm->plotList1();
_vm->copyBlocks();
}
void AmazonScripts::mWhile1() {
_vm->_screen->setDisplayScan();
_vm->_screen->fadeOut();
_vm->_events->hideCursor();
_vm->_files->loadScreen(14, 0);
_vm->_buffer2.blitFrom(*_vm->_screen);
_vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
_vm->_screen->forceFadeIn();
Resource *spriteData = _vm->_files->loadFile(14, 6);
_vm->_objectsTable[0] = new SpriteResource(_vm, spriteData);
delete spriteData;
_vm->_images.clear();
_vm->_oldRects.clear();
_sequence = 2100;
do {
cLoop();
_sequence = 2100;
} while (_vm->_flags[52] == 1);
_vm->_buffer1.copyTo(_vm->_screen);
_vm->_buffer2.copyTo(&_vm->_buffer1);
_game->establish(-1, 14);
spriteData = _vm->_files->loadFile(14, 7);
_vm->_objectsTable[1] = new SpriteResource(_vm, spriteData);
delete spriteData;
_vm->_sound->playSound(0);
_vm->_screen->setDisplayScan();
_vm->_events->hideCursor();
_vm->_files->loadScreen(14, 1);
_vm->_screen->setPalette();
_vm->_buffer2.blitFrom(*_vm->_screen);
_vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
_vm->_images.clear();
_vm->_oldRects.clear();
_sequence = 2200;
_vm->_sound->loadSoundTable(0, 14, 15);
do {
cLoop();
_sequence = 2200;
} while (_vm->_flags[52] == 2);
_vm->_screen->setDisplayScan();
_vm->_events->hideCursor();
_vm->_files->loadScreen(14, 2);
_vm->_screen->setPalette();
_vm->_buffer2.blitFrom(*_vm->_screen);
_vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
_vm->freeCells();
spriteData = _vm->_files->loadFile(14, 8);
_vm->_objectsTable[2] = new SpriteResource(_vm, spriteData);
delete spriteData;
_vm->_images.clear();
_vm->_oldRects.clear();
_sequence = 2300;
_vm->_sound->playSound(0);
do {
cLoop();
_sequence = 2300;
} while (_vm->_flags[52] == 3);
_vm->freeCells();
spriteData = _vm->_files->loadFile(14, 9);
_vm->_objectsTable[3] = new SpriteResource(_vm, spriteData);
delete spriteData;
_vm->_screen->setDisplayScan();
_vm->_events->hideCursor();
_vm->_files->loadScreen(14, 3);
_vm->_screen->setPalette();
_vm->_buffer2.blitFrom(*_vm->_screen);
_vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
_vm->_images.clear();
_vm->_oldRects.clear();
_sequence = 2400;
do {
cLoop();
_sequence = 2400;
} while (_vm->_flags[52] == 4);
}
void AmazonScripts::mWhile2() {
_vm->_screen->setDisplayScan();
_vm->_screen->fadeOut();
_vm->_events->hideCursor();
_vm->_files->loadScreen(14, 0);
_vm->_buffer2.blitFrom(*_vm->_screen);
_vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
_vm->_screen->forceFadeIn();
Resource *spriteData = _vm->_files->loadFile(14, 6);
_vm->_objectsTable[0] = new SpriteResource(_vm, spriteData);
delete spriteData;
_vm->_images.clear();
_vm->_oldRects.clear();
_sequence = 2100;
do {
cLoop();
_sequence = 2100;
} while (_vm->_flags[52] == 1);
_vm->_screen->fadeOut();
_vm->freeCells();
spriteData = _vm->_files->loadFile(14, 9);
_vm->_objectsTable[3] = new SpriteResource(_vm, spriteData);
delete spriteData;
_vm->_screen->setDisplayScan();
_vm->_events->hideCursor();
_vm->_files->loadScreen(14, 3);
_vm->_screen->setPalette();
_vm->_buffer2.blitFrom(*_vm->_screen);
_vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
_vm->_images.clear();
_vm->_oldRects.clear();
_sequence = 2400;
do {
cLoop();
_sequence = 2400;
} while (_vm->_flags[52] == 4);
}
void AmazonScripts::mWhile(int param1) {
switch(param1) {
case 1:
mWhile1();
break;
case 2:
_game->_plane->mWhileFly();
break;
case 3:
_game->_plane->mWhileFall();
break;
case 4:
_game->_jungle->mWhileJWalk();
break;
case 5:
_game->_jungle->mWhileDoOpen();
break;
case 6:
_game->_river->mWhileDownRiver();
break;
case 7:
mWhile2();
break;
case 8:
_game->_jungle->mWhileJWalk2();
break;
default:
break;
}
}
void AmazonScripts::loadBackground(int param1, int param2) {
_vm->_files->_setPaletteFlag = false;
_vm->_files->loadScreen(param1, param2);
_vm->_buffer2.blitFrom(*_vm->_screen);
_vm->_buffer1.blitFrom(*_vm->_screen);
_vm->_screen->forceFadeIn();
}
void AmazonScripts::loadNSound(int param1, int param2) {
Resource *sound = _vm->_files->loadFile(param1, param2);
_vm->_sound->_soundTable.push_back(SoundEntry(sound, 1));
}
void AmazonScripts::setInactive() {
_game->_rawInactiveX = _vm->_player->_rawPlayer.x;
_game->_rawInactiveY = _vm->_player->_rawPlayer.y;
_game->_charSegSwitch = false;
mWhile(_game->_rawInactiveY);
}
void AmazonScripts::boatWalls(int param1, int param2) {
if (param1 == 1)
_vm->_room->_plotter._walls[42] = Common::Rect(96, 27, 96 + 87, 27 + 42);
else {
_vm->_room->_plotter._walls[39].bottom = _vm->_room->_plotter._walls[41].bottom = 106;
_vm->_room->_plotter._walls[40].left = 94;
}
}
void AmazonScripts::plotInactive() {
Player &player = *_vm->_player;
InactivePlayer &inactive = _game->_inactive;
if (_game->_charSegSwitch) {
_game->_currentCharFlag = true;
SWAP(inactive._altSpritesPtr, player._playerSprites);
_game->_charSegSwitch = false;
} else if (_game->_jasMayaFlag != (_game->_currentCharFlag ? 1 : 0)) {
if (player._playerOff) {
_game->_jasMayaFlag = (_game->_currentCharFlag ? 1 : 0);
} else {
_game->_currentCharFlag = (_game->_jasMayaFlag == 1);
int tmpX = _game->_rawInactiveX;
int tmpY = _game->_rawInactiveY;
_game->_rawInactiveX = player._rawPlayer.x;
_game->_rawInactiveY = player._rawPlayer.y;
player._rawPlayer.x = tmpX;
player._rawPlayer.y = tmpY;
_game->_inactiveYOff = player._playerOffset.y;
player.calcManScale();
SWAP(inactive._altSpritesPtr, player._playerSprites);
_vm->_room->setWallCodes();
}
}
_game->_flags[155] = 0;
if (_game->_rawInactiveX >= 152 && _game->_rawInactiveX <= 167 &&
_game->_rawInactiveY >= 158 && _game->_rawInactiveY <= 173) {
_game->_flags[155] = 1;
} else {
_game->_flags[160] = 0;
if (!_game->_jasMayaFlag && _game->_rawInactiveX >= 266 && _game->_rawInactiveX <= 290
&& _game->_rawInactiveY >= 70 && _game->_rawInactiveY <= 87) {
_game->_flags[160] = 1;
}
}
inactive._flags &= ~IMGFLAG_UNSCALED;
inactive._flags &= ~IMGFLAG_BACKWARDS;
inactive._position.x = _game->_rawInactiveX;
inactive._position.y = _game->_rawInactiveY - _game->_inactiveYOff;
inactive._offsetY = _game->_inactiveYOff;
inactive._spritesPtr = inactive._altSpritesPtr;
_vm->_images.addToList(_game->_inactive);
}
void AmazonScripts::executeSpecial(int commandIndex, int param1, int param2) {
switch (commandIndex) {
case 0:
warning("TODO: DEMO - RESETAN");
break;
case 1:
_vm->establish(param1, param2);
break;
case 2:
loadBackground(param1, param2);
break;
case 3:
if (_vm->isDemo())
warning("TODO: DEMO - LOADCELLSET");
else
_game->_cast->doCast(param1);
break;
case 4:
if (_vm->isDemo())
loadNSound(param1, param2);
else
setInactive();
break;
case 5:
warning("TODO: DEMO - UNLOADCELLSET");
break;
case 6:
mWhile(param1);
break;
case 7:
warning("TODO: DEMO - ADDMONEY");
break;
case 8:
warning("TODO: DEMO - CHKMONEY");
break;
case 9:
_game->_guard->doGuard();
break;
case 10:
_vm->_midi->newMusic(param1, param2);
break;
case 11:
plotInactive();
break;
case 13:
_game->_river->doRiver();
break;
case 14:
_game->_ant->doAnt();
break;
case 15:
boatWalls(param1, param2);
break;
default:
warning("Unexpected Special code %d - Skipped", commandIndex);
}
}
typedef void(AmazonScripts::*AmazonScriptMethodPtr)();
void AmazonScripts::executeCommand(int commandIndex) {
static const AmazonScriptMethodPtr AMAZON_COMMAND_LIST[] = {
&AmazonScripts::cmdHelp_v2, &AmazonScripts::cmdCycleBack,
&AmazonScripts::cmdChapter, &AmazonScripts::cmdSetHelp,
&AmazonScripts::cmdCenterPanel, &AmazonScripts::cmdMainPanel,
&AmazonScripts::CMDRETFLASH
};
if (commandIndex >= 73)
(this->*AMAZON_COMMAND_LIST[commandIndex - 73])();
else
Scripts::executeCommand(commandIndex);
}
void AmazonScripts::cmdHelp_v2() {
Common::String helpMessage = readString();
if (_game->_helpLevel == 0) {
_game->_timers.saveTimers();
_game->_useItem = 0;
if (_game->_noHints) {
printString(AMRES.NO_HELP_MESSAGE);
return;
} else if (_game->_hintLevel == 0) {
printString(AMRES.NO_HINTS_MESSAGE);
return;
}
}
int level = _game->_hintLevel - 1;
if (level < _game->_helpLevel)
_game->_moreHelp = 0;
_game->drawHelp(helpMessage);
while (!_vm->shouldQuit()) {
while (!_vm->shouldQuit() && !_vm->_events->_leftButton)
_vm->_events->pollEventsAndWait();
_vm->_events->debounceLeft();
static const Common::Rect butn1 = Common::Rect(HELP1COORDS[0][0], HELP1COORDS[0][2], HELP1COORDS[0][1], HELP1COORDS[0][3]);
static const Common::Rect butn2 = Common::Rect(HELP1COORDS[1][0], HELP1COORDS[1][2], HELP1COORDS[1][1], HELP1COORDS[1][3]);
const Common::Point pt = _vm->_events->_mousePos;
int choice = -1;
if (butn1.contains(pt))
choice = 0;
else if (butn2.contains(pt))
choice = 1;
if (choice < 0)
continue;
if (choice == 1) {
// Done button selected
_game->_helpLevel = 0;
_game->_moreHelp = 1;
_game->_useItem = 0;
_vm->_events->hideCursor();
if (_vm->_screen->_vesaMode) {
_vm->_screen->restoreScreen();
_vm->_screen->setPanel(0);
} else {
_vm->_screen->fadeOut();
_vm->_screen->clearBuffer();
}
_vm->_buffer2.copyTo(_vm->_screen);
_vm->_screen->restorePalette();
_vm->_screen->setPalette();
_vm->_events->showCursor();
delete _vm->_objectsTable[45];
_vm->_objectsTable[45] = nullptr;
_vm->_timers.restoreTimers();
break;
} else {
// More button selected
if ((_game->_moreHelp == 0) || (choice != 0))
continue;
++_game->_helpLevel;
_game->_useItem = 1;
break;
}
}
findNull();
}
void AmazonScripts::cmdCycleBack() {
if (_vm->_startup == -1)
_vm->_screen->cyclePaletteBackwards();
}
void AmazonScripts::cmdChapter() {
Resource *activeScript = nullptr;
if (_vm->isDemo()) {
cmdSetHelp();
} else {
int chapter = _data->readByte();
if (!_vm->isCD()) {
// For floppy version, the current script remains active even
// after the end of the chapter start, so we need to save it
activeScript = _resource;
_resource = nullptr;
_data = nullptr;
}
_game->startChapter(chapter);
if (!_vm->isCD()) {
assert(!_resource);
setScript(activeScript, false);
}
}
}
void AmazonScripts::cmdSetHelp() {
int arrayId = (_data->readUint16LE() & 0xFF) - 1;
int helpId = _data->readUint16LE() & 0xFF;
byte *help = _game->_helpTbl[arrayId];
help[helpId] = 1;
if (_vm->_useItem == 0) {
_sequence = 11000;
searchForSequence();
}
}
void AmazonScripts::cmdCenterPanel() {
if (_vm->_screen->_vesaMode) {
_vm->_screen->clearScreen();
_vm->_screen->setPanel(3);
}
}
void AmazonScripts::cmdMainPanel() {
if (_vm->_screen->_vesaMode) {
_vm->_room->init4Quads();
_vm->_screen->setPanel(0);
}
}
void AmazonScripts::CMDRETFLASH() {
error("TODO CMDRETFLASH");
}
} // End of namespace Amazon
} // End of namespace Access