Initial commit
This commit is contained in:
944
engines/access/player.cpp
Normal file
944
engines/access/player.cpp
Normal file
@@ -0,0 +1,944 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/algorithm.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "access/player.h"
|
||||
#include "access/access.h"
|
||||
#include "access/resources.h"
|
||||
#include "access/amazon/amazon_player.h"
|
||||
#include "access/martian/martian_player.h"
|
||||
|
||||
namespace Access {
|
||||
|
||||
Player *Player::init(AccessEngine *vm) {
|
||||
switch (vm->getGameID()) {
|
||||
case kGameAmazon:
|
||||
vm->_playerDataCount = 8;
|
||||
return new Amazon::AmazonPlayer(vm);
|
||||
case kGameMartianMemorandum:
|
||||
vm->_playerDataCount = 10;
|
||||
return new Martian::MartianPlayer(vm);
|
||||
default:
|
||||
vm->_playerDataCount = 8;
|
||||
return new Player(vm);
|
||||
}
|
||||
}
|
||||
|
||||
Player::Player(AccessEngine *vm) : Manager(vm), ImageEntry() {
|
||||
_playerSprites = nullptr;
|
||||
_playerSprites1 = nullptr;
|
||||
_manPal1 = nullptr;
|
||||
_frameNumber = 0;
|
||||
_rawTempL = 0;
|
||||
_rawXTemp = 0;
|
||||
_rawYTempL = 0;
|
||||
_rawYTemp = 0;
|
||||
_playerXLow = 0;
|
||||
_playerX = 0;
|
||||
_playerYLow = 0;
|
||||
_playerY = 0;
|
||||
_frame = 0;
|
||||
_playerOff = false;
|
||||
_playerMove = false;
|
||||
_leftDelta = _rightDelta = 0;
|
||||
_upDelta = _downDelta = 0;
|
||||
_scrollConst = 0;
|
||||
_scrollFlag = false;
|
||||
_scrollThreshold = 0;
|
||||
_scrollAmount = 0;
|
||||
_scrollEnd = 0;
|
||||
_roomNumber = 0;
|
||||
_collideFlag = false;
|
||||
_move = NONE;
|
||||
_playerDirection = NONE;
|
||||
_xFlag = _yFlag = 0;
|
||||
_inactiveYOff = 0;
|
||||
_jetpackFlag = 0;
|
||||
|
||||
_sideWalkMin = _sideWalkMax = 0;
|
||||
_upWalkMin = _upWalkMax = 0;
|
||||
_downWalkMin = _downWalkMax = 0;
|
||||
_diagUpWalkMin = _diagUpWalkMax = 0;
|
||||
_diagDownWalkMin = _diagDownWalkMax = 0;
|
||||
_walkOffRight = _walkOffLeft = nullptr;
|
||||
_walkOffUp = _walkOffDown = nullptr;
|
||||
_walkOffUR = _walkOffDR = nullptr;
|
||||
_walkOffUL = _walkOffDL = nullptr;
|
||||
}
|
||||
|
||||
Player::~Player() {
|
||||
delete _playerSprites;
|
||||
delete[] _manPal1;
|
||||
delete[] _walkOffRight;
|
||||
delete[] _walkOffLeft;
|
||||
delete[] _walkOffUp;
|
||||
delete[] _walkOffDown;
|
||||
delete[] _walkOffUR;
|
||||
delete[] _walkOffDR;
|
||||
delete[] _walkOffUL;
|
||||
delete[] _walkOffDL;
|
||||
}
|
||||
|
||||
void Player::load() {
|
||||
uint8 dataCount = _vm->_playerDataCount;
|
||||
_walkOffRight = new int[dataCount];
|
||||
_walkOffLeft = new int[dataCount];
|
||||
_walkOffUp = new int[dataCount];
|
||||
_walkOffDown = new int[dataCount];
|
||||
_walkOffUR = new Common::Point[dataCount];
|
||||
_walkOffDR = new Common::Point[dataCount];
|
||||
_walkOffUL = new Common::Point[dataCount];
|
||||
_walkOffDL = new Common::Point[dataCount];
|
||||
|
||||
// NOTE: Although the values get set here to Amazon defaults, they are overridden
|
||||
// in both AmazonPlayer and MartianPlayer load() functions.
|
||||
_playerOffset.x = _vm->_screen->_scaleTable1[25];
|
||||
_playerOffset.y = _vm->_screen->_scaleTable1[67];
|
||||
_leftDelta = -3;
|
||||
_rightDelta = 33;
|
||||
_upDelta = 5;
|
||||
_downDelta = -10;
|
||||
_scrollConst = 5;
|
||||
|
||||
_sideWalkMin = 0;
|
||||
_sideWalkMax = 7;
|
||||
_upWalkMin = 16;
|
||||
_upWalkMax = 23;
|
||||
_downWalkMin = 8;
|
||||
_downWalkMax = 15;
|
||||
_diagUpWalkMin = 0;
|
||||
_diagUpWalkMax = 7;
|
||||
_diagDownWalkMin = 0;
|
||||
_diagDownWalkMax = 7;
|
||||
|
||||
_playerSprites = _playerSprites1;
|
||||
if (_manPal1) {
|
||||
// Those values are from MM as Amazon doesn't use it
|
||||
Common::copy(_manPal1 + 0x2A0, _manPal1 + 0x2A0 + 0x42, _vm->_screen->_manPal);
|
||||
} else {
|
||||
Common::fill(_vm->_screen->_manPal, _vm->_screen->_manPal + 0x60, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::loadTexPalette() {
|
||||
Resource *texPal = _vm->_files->loadFile("TEXPAL.COL");
|
||||
int size = texPal->_size;
|
||||
assert(size == 768);
|
||||
_manPal1 = new byte[size];
|
||||
memcpy(_manPal1, texPal->data(), size);
|
||||
}
|
||||
|
||||
void Player::loadSprites(const Common::Path &name) {
|
||||
freeSprites();
|
||||
|
||||
Resource *data = _vm->_files->loadFile(name);
|
||||
|
||||
#if 0
|
||||
Common::DumpFile *outFile = new Common::DumpFile();
|
||||
Common::String outName = name + ".dump";
|
||||
outFile->open(outName);
|
||||
outFile->write(data->data(), data->_size);
|
||||
outFile->finalize();
|
||||
outFile->close();
|
||||
#endif
|
||||
|
||||
_playerSprites1 = new SpriteResource(_vm, data);
|
||||
delete data;
|
||||
}
|
||||
|
||||
void Player::freeSprites() {
|
||||
delete _playerSprites;
|
||||
_playerSprites1 = nullptr;
|
||||
_playerSprites = nullptr;
|
||||
}
|
||||
|
||||
void Player::removeSprite1() {
|
||||
if (_playerSprites1) {
|
||||
delete _playerSprites1;
|
||||
_playerSprites1 = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Player::isMMHover() const {
|
||||
// Whether or not this is MM and the player is on the hoverboard.
|
||||
return (_vm->getGameID() == kGameMartianMemorandum &&
|
||||
_vm->_flags[174] == 1);
|
||||
}
|
||||
|
||||
void Player::calcManScale() {
|
||||
if (!_vm->_manScaleOff) {
|
||||
_vm->_scale = ((((_rawPlayer.y - _vm->_scaleMaxY + _vm->_scaleN1) *
|
||||
_vm->_scaleT1 + (_vm->_scaleH2 << 8)) & 0xff00) / _vm->_scaleH1 * _vm->_scaleI) >> 8;
|
||||
_vm->_screen->setScaleTable(_vm->_scale);
|
||||
|
||||
_playerOffset.x = _vm->_screen->_scaleTable1[20];
|
||||
_playerOffset.y = _vm->_screen->_scaleTable1[(_vm->getGameID() == kGameMartianMemorandum) ? 62 : 67];
|
||||
_inactiveYOff = _playerOffset.y;
|
||||
}
|
||||
}
|
||||
|
||||
void Player::jetpack() {
|
||||
_playerDirection = UP;
|
||||
ImageFlag flags = IMGFLAG_NONE;
|
||||
if (!_vm->_timers[0]._flag) {
|
||||
_vm->_timers[0]._flag = 1;
|
||||
_jetpackFlag ^= 1;
|
||||
_rawPlayer.y -= 4;
|
||||
if (_move == RIGHT) {
|
||||
_frame = 0;
|
||||
flags = IMGFLAG_CROPPED;
|
||||
if (_rawPlayer.x < 0x101)
|
||||
_rawPlayer.x += 2;
|
||||
else
|
||||
_rawPlayer.x = 256;
|
||||
}
|
||||
if (_move == LEFT) {
|
||||
_frame = 0;
|
||||
flags = IMGFLAG_BACKWARDS;
|
||||
_rawPlayer.x -= 2;
|
||||
if (_rawPlayer.x < 0)
|
||||
_rawPlayer.x = 0;
|
||||
}
|
||||
|
||||
// Leave tex facing whichever direction he was previously
|
||||
// unless moving in some direction
|
||||
if (_move == LEFT || _move == RIGHT)
|
||||
_flags = (_flags & 0xfd) | flags;
|
||||
}
|
||||
|
||||
_flags |= IMGFLAG_UNSCALED;
|
||||
|
||||
_position.x = _rawPlayer.x;
|
||||
_position.y = _rawPlayer.y - _playerOffset.y;
|
||||
_offsetY = _playerOffset.y;
|
||||
_frameNumber = 23 + _jetpackFlag;
|
||||
|
||||
ImageEntry ie = *this;
|
||||
ie._spritesPtr = _vm->_objectsTable[35];
|
||||
_vm->_images.addToList(ie);
|
||||
}
|
||||
|
||||
void Player::walk() {
|
||||
_collideFlag = false;
|
||||
|
||||
if (_vm->getGameID() == kGameMartianMemorandum && _vm->_flags[173] == 1) {
|
||||
// Special case for MM Jetpack
|
||||
jetpack();
|
||||
return;
|
||||
}
|
||||
|
||||
_playerDirection = NONE;
|
||||
|
||||
if (_playerOff)
|
||||
return;
|
||||
else if (_vm->_timers[0]._flag) {
|
||||
plotCom3();
|
||||
return;
|
||||
}
|
||||
|
||||
++_vm->_timers[0]._flag;
|
||||
switch (_move) {
|
||||
case UP:
|
||||
_playerMove = false;
|
||||
walkUp();
|
||||
break;
|
||||
case DOWN:
|
||||
_playerMove = false;
|
||||
walkDown();
|
||||
break;
|
||||
case LEFT:
|
||||
_playerMove = false;
|
||||
walkLeft();
|
||||
break;
|
||||
case RIGHT:
|
||||
_playerMove = false;
|
||||
walkRight();
|
||||
break;
|
||||
case UPLEFT:
|
||||
_playerMove = false;
|
||||
walkUpLeft();
|
||||
break;
|
||||
case DOWNLEFT:
|
||||
_playerMove = false;
|
||||
walkDownLeft();
|
||||
break;
|
||||
case UPRIGHT:
|
||||
_playerMove = false;
|
||||
walkUpRight();
|
||||
break;
|
||||
case DOWNRIGHT:
|
||||
_playerMove = false;
|
||||
walkDownRight();
|
||||
break;
|
||||
default:
|
||||
checkMove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Player::calcPlayer() {
|
||||
Screen &scr = *_vm->_screen;
|
||||
scr._bufferStart.x = (_vm->_scrollCol << 4) + _vm->_scrollX;
|
||||
scr._bufferStart.y = (_vm->_scrollRow << 4) + _vm->_scrollY;
|
||||
_playerX = _rawPlayer.x - scr._bufferStart.x;
|
||||
_playerY = _rawPlayer.y - scr._bufferStart.y;
|
||||
}
|
||||
|
||||
void Player::walkUp() {
|
||||
if (_frame > _upWalkMax || _frame < _upWalkMin)
|
||||
_frame = _upWalkMin;
|
||||
|
||||
_playerDirection = UP;
|
||||
int walkOff = _walkOffUp[_frame - _upWalkMin];
|
||||
int tempL = _rawPlayerLow.y - (isMMHover() ? 2 : _vm->_screen->_scaleTable2[walkOff]);
|
||||
_rawYTempL = (byte)tempL;
|
||||
int yTemp = _rawPlayer.y - (isMMHover() ? 2 : _vm->_screen->_scaleTable1[walkOff]) -
|
||||
(tempL < 0 ? 1 : 0);
|
||||
_rawYTemp = yTemp;
|
||||
_rawXTemp = _rawPlayer.x;
|
||||
|
||||
if (_vm->_room->codeWalls()) {
|
||||
plotCom2();
|
||||
} else {
|
||||
_rawPlayer.y = _rawYTemp;
|
||||
_rawPlayerLow.y = _rawYTempL;
|
||||
|
||||
calcManScale();
|
||||
|
||||
if (_vm->getGameID() == kGameMartianMemorandum && _vm->_flags[174] == 0 && (_frame == 8 || _frame == 12))
|
||||
_vm->_sound->playSound(0);
|
||||
else if (_vm->getGameID() == kGameAmazon && _vm->_currentMan != 3 && (_frame == 17 || _frame == 21))
|
||||
_vm->_sound->playSound(0);
|
||||
|
||||
if (++_frame > _upWalkMax)
|
||||
_frame = _upWalkMin;
|
||||
|
||||
plotCom(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::walkDown() {
|
||||
if (_frame > _downWalkMax || _frame < _downWalkMin)
|
||||
_frame = _downWalkMin;
|
||||
|
||||
_playerDirection = DOWN;
|
||||
int walkOff = _walkOffDown[_frame - _downWalkMin];
|
||||
int tempL = (isMMHover() ? 2 : _vm->_screen->_scaleTable2[walkOff]) + _rawPlayerLow.y;
|
||||
_rawYTempL = (byte)tempL;
|
||||
_rawYTemp = (isMMHover() ? 2 : _vm->_screen->_scaleTable1[walkOff]) + _rawPlayer.y + (tempL >= 0x100 ? 1 : 0);
|
||||
_rawXTemp = _rawPlayer.x;
|
||||
|
||||
if (_vm->_room->codeWalls()) {
|
||||
plotCom2();
|
||||
} else {
|
||||
_rawPlayer.y = _rawYTemp;
|
||||
_rawPlayerLow.y = _rawYTempL;
|
||||
|
||||
calcManScale();
|
||||
|
||||
if (_vm->getGameID() == kGameMartianMemorandum && _vm->_flags[174] == 0 && (_frame == 17 || _frame == 21))
|
||||
_vm->_sound->playSound(0);
|
||||
else if (_vm->getGameID() == kGameAmazon && _vm->_currentMan != 3 && (_frame == 10 || _frame == 14))
|
||||
_vm->_sound->playSound(0);
|
||||
|
||||
if (++_frame > _downWalkMax)
|
||||
_frame = _downWalkMin;
|
||||
|
||||
plotCom(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::walkLeft() {
|
||||
if (_frame > _sideWalkMax || _frame < _sideWalkMin)
|
||||
_frame = _sideWalkMin;
|
||||
|
||||
_playerDirection = LEFT;
|
||||
|
||||
bool flag = _scrollEnd == 1;
|
||||
if (!flag) {
|
||||
calcPlayer();
|
||||
flag = (_playerX - _vm->_screen->_scaleTable1[_scrollConst] -
|
||||
_vm->_player->_scrollThreshold) > 0;
|
||||
}
|
||||
if (flag) {
|
||||
int walkOffset = _walkOffLeft[_frame - _sideWalkMin];
|
||||
int tempL = _rawPlayerLow.x - (isMMHover() ? 2 : _vm->_screen->_scaleTable2[walkOffset]);
|
||||
_rawTempL = (byte)tempL;
|
||||
_rawXTemp = _rawPlayer.x - (isMMHover() ? 2 : _vm->_screen->_scaleTable1[walkOffset]) -
|
||||
(tempL < 0 ? 1 : 0);
|
||||
} else {
|
||||
_rawXTemp = _rawPlayer.x - _vm->_screen->_scaleTable1[_scrollConst];
|
||||
}
|
||||
_rawYTemp = _rawPlayer.y;
|
||||
|
||||
if (_vm->_room->codeWalls()) {
|
||||
plotCom2();
|
||||
} else {
|
||||
_rawPlayer.x = _rawXTemp;
|
||||
_rawPlayerLow.x = _rawTempL;
|
||||
++_frame;
|
||||
|
||||
if (_vm->getGameID() == kGameMartianMemorandum && _vm->_flags[174] == 0 && (_frame == 7 || _frame == 3))
|
||||
_vm->_sound->playSound(0);
|
||||
else if (_vm->getGameID() == kGameAmazon && _vm->_currentMan != 3 && (_frame == 1 || _frame == 5))
|
||||
_vm->_sound->playSound(0);
|
||||
|
||||
if (_frame > _sideWalkMax)
|
||||
_frame = _sideWalkMin;
|
||||
|
||||
plotCom1();
|
||||
}
|
||||
}
|
||||
|
||||
void Player::walkRight() {
|
||||
if (_frame > _sideWalkMax || _frame < _sideWalkMin)
|
||||
_frame = _sideWalkMin;
|
||||
|
||||
_playerDirection = RIGHT;
|
||||
|
||||
bool flag = _scrollEnd == 2;
|
||||
if (!flag) {
|
||||
calcPlayer();
|
||||
flag = (_vm->_screen->_clipWidth - _playerX - _vm->_screen->_scaleTable1[_scrollConst] -
|
||||
_vm->_player->_scrollThreshold) > 0;
|
||||
}
|
||||
if (flag) {
|
||||
int walkOffset = _walkOffRight[_frame - _sideWalkMin];
|
||||
int tempL = _rawPlayerLow.x + (isMMHover() ? 2 : _vm->_screen->_scaleTable2[walkOffset]);
|
||||
_rawTempL = (byte)tempL;
|
||||
_rawXTemp = _rawPlayer.x + (isMMHover() ? 2 : _vm->_screen->_scaleTable1[walkOffset]) +
|
||||
(tempL >= 0x100 ? 1 : 0);
|
||||
} else {
|
||||
_rawXTemp = _rawPlayer.x + _vm->_screen->_scaleTable1[_scrollConst];
|
||||
}
|
||||
_rawYTemp = _rawPlayer.y;
|
||||
|
||||
if (_vm->_room->codeWalls()) {
|
||||
plotCom2();
|
||||
} else {
|
||||
_rawPlayer.x = _rawXTemp;
|
||||
_rawPlayerLow.x = _rawTempL;
|
||||
++_frame;
|
||||
|
||||
if (_vm->getGameID() == kGameMartianMemorandum && _vm->_flags[174] == 0 && (_frame == 7 || _frame == 3))
|
||||
_vm->_sound->playSound(0);
|
||||
else if (_vm->getGameID() == kGameAmazon && _vm->_currentMan != 3 && (_frame == 1 || _frame == 5))
|
||||
_vm->_sound->playSound(0);
|
||||
|
||||
// Useless check removed
|
||||
if (_frame > _sideWalkMax)
|
||||
_frame = _sideWalkMin;
|
||||
|
||||
plotCom0();
|
||||
}
|
||||
}
|
||||
|
||||
void Player::walkUpLeft() {
|
||||
if (_frame > _diagUpWalkMax || _frame < _diagUpWalkMin)
|
||||
_frame = _diagUpWalkMin;
|
||||
|
||||
_playerDirection = UPLEFT;
|
||||
|
||||
int walkOffset, tempL;
|
||||
bool flag = _scrollEnd == 1;
|
||||
if (!flag) {
|
||||
calcPlayer();
|
||||
flag = (_playerX - _vm->_screen->_scaleTable1[_scrollConst] -
|
||||
_vm->_player->_scrollThreshold) > 0;
|
||||
}
|
||||
if (flag) {
|
||||
walkOffset = _walkOffUL[_frame - _diagUpWalkMin].x;
|
||||
tempL = _rawPlayerLow.x - _vm->_screen->_scaleTable2[walkOffset];
|
||||
_rawTempL = (byte)tempL;
|
||||
_rawXTemp = _rawPlayer.x - _vm->_screen->_scaleTable1[walkOffset] -
|
||||
(tempL < 0 ? 1 : 0);
|
||||
} else {
|
||||
_rawXTemp = _rawPlayer.x - _vm->_screen->_scaleTable1[_scrollConst];
|
||||
}
|
||||
|
||||
walkOffset = _walkOffUL[_frame - _diagUpWalkMin].y;
|
||||
tempL = _rawPlayerLow.y - _vm->_screen->_scaleTable2[walkOffset];
|
||||
_rawYTempL = (byte)tempL;
|
||||
_rawYTemp = _rawPlayer.y - _vm->_screen->_scaleTable1[walkOffset] -
|
||||
(tempL < 0 ? 1 : 0);
|
||||
|
||||
if (_vm->_room->codeWalls()) {
|
||||
plotCom2();
|
||||
} else {
|
||||
_rawPlayer.x = _rawXTemp;
|
||||
_rawPlayer.y = _rawYTemp;
|
||||
_rawPlayerLow.x = _rawTempL;
|
||||
_rawPlayerLow.y = _rawYTempL;
|
||||
|
||||
++_frame;
|
||||
calcManScale();
|
||||
|
||||
if (_vm->_currentMan != 3 && (_frame == 1 || _frame == 5))
|
||||
_vm->_sound->playSound(0);
|
||||
|
||||
if (_frame > _diagUpWalkMax)
|
||||
_frame = _diagUpWalkMin;
|
||||
|
||||
plotCom1();
|
||||
}
|
||||
}
|
||||
|
||||
void Player::walkDownLeft() {
|
||||
if (_frame > _diagDownWalkMax || _frame < _diagDownWalkMin)
|
||||
_frame = _diagDownWalkMin;
|
||||
|
||||
_playerDirection = DOWNLEFT;
|
||||
|
||||
int walkOffset, tempL;
|
||||
bool flag = _scrollEnd == 1;
|
||||
if (!flag) {
|
||||
calcPlayer();
|
||||
flag = (_playerX - _vm->_screen->_scaleTable1[_scrollConst] -
|
||||
_vm->_player->_scrollThreshold) > 0;
|
||||
}
|
||||
if (flag) {
|
||||
walkOffset = _walkOffDL[_frame - _sideWalkMin].x;
|
||||
tempL = _rawPlayerLow.x - _vm->_screen->_scaleTable2[walkOffset];
|
||||
_rawTempL = (byte)tempL;
|
||||
_rawXTemp = _rawPlayer.x - _vm->_screen->_scaleTable1[walkOffset] -
|
||||
(tempL < 0 ? 1 : 0);
|
||||
} else {
|
||||
_rawXTemp = _rawPlayer.x - _vm->_screen->_scaleTable1[_scrollConst];
|
||||
}
|
||||
|
||||
walkOffset = _walkOffDL[_frame - _diagDownWalkMin].y;
|
||||
tempL = _rawPlayerLow.y + _vm->_screen->_scaleTable2[walkOffset];
|
||||
_rawYTempL = (byte)tempL;
|
||||
_rawYTemp = _rawPlayer.y + _vm->_screen->_scaleTable1[walkOffset] +
|
||||
(tempL >= 0x100 ? 1 : 0);
|
||||
|
||||
if (_vm->_room->codeWalls()) {
|
||||
plotCom2();
|
||||
} else {
|
||||
_rawPlayer.x = _rawXTemp;
|
||||
_rawPlayer.y = _rawYTemp;
|
||||
_rawPlayerLow.x = _rawTempL;
|
||||
_rawPlayerLow.y = _rawYTempL;
|
||||
|
||||
++_frame;
|
||||
calcManScale();
|
||||
|
||||
if (_vm->_currentMan != 3 && (_frame == 1 || _frame == 5))
|
||||
_vm->_sound->playSound(0);
|
||||
|
||||
if (_frame > _diagDownWalkMax)
|
||||
_frame = _diagDownWalkMin;
|
||||
|
||||
plotCom1();
|
||||
}
|
||||
}
|
||||
|
||||
void Player::walkUpRight() {
|
||||
if (_frame > _diagUpWalkMax || _frame < _diagUpWalkMin)
|
||||
_frame = _diagUpWalkMin;
|
||||
|
||||
_playerDirection = UPRIGHT;
|
||||
|
||||
int walkOffset, tempL;
|
||||
bool flag = _scrollEnd == 1;
|
||||
if (!flag) {
|
||||
calcPlayer();
|
||||
flag = (_vm->_screen->_clipWidth - _playerX - _vm->_screen->_scaleTable1[_scrollConst] -
|
||||
_vm->_player->_scrollThreshold) > 0;
|
||||
}
|
||||
if (flag) {
|
||||
walkOffset = _walkOffUR[_frame - _diagUpWalkMin].x;
|
||||
tempL = _rawPlayerLow.x + _vm->_screen->_scaleTable2[walkOffset];
|
||||
_rawTempL = (byte)tempL;
|
||||
_rawXTemp = _rawPlayer.x + _vm->_screen->_scaleTable1[walkOffset] +
|
||||
(tempL >= 0x100 ? 1 : 0);
|
||||
} else {
|
||||
_rawXTemp = _rawPlayer.x + _vm->_screen->_scaleTable1[_scrollConst];
|
||||
}
|
||||
|
||||
walkOffset = _walkOffUL[_frame - _diagUpWalkMin].y;
|
||||
tempL = _rawPlayerLow.y - _vm->_screen->_scaleTable2[walkOffset];
|
||||
_rawYTempL = (byte)tempL;
|
||||
_rawYTemp = _rawPlayer.y - _vm->_screen->_scaleTable1[walkOffset] -
|
||||
(tempL < 0 ? 1 : 0);
|
||||
|
||||
if (_vm->_room->codeWalls()) {
|
||||
plotCom2();
|
||||
} else {
|
||||
_rawPlayer.x = _rawXTemp;
|
||||
_rawPlayer.y = _rawYTemp;
|
||||
_rawPlayerLow.x = _rawTempL;
|
||||
_rawPlayerLow.y = _rawYTempL;
|
||||
|
||||
++_frame;
|
||||
calcManScale();
|
||||
|
||||
if (_vm->_currentMan != 3 && (_frame == 1 || _frame == 5))
|
||||
_vm->_sound->playSound(0);
|
||||
|
||||
if (_frame > _diagUpWalkMax)
|
||||
_frame = _diagUpWalkMin;
|
||||
|
||||
plotCom(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::walkDownRight() {
|
||||
if (_frame > _diagDownWalkMax || _frame < _diagDownWalkMin)
|
||||
_frame = _diagDownWalkMin;
|
||||
|
||||
_playerDirection = DOWNRIGHT;
|
||||
|
||||
int walkOffset, tempL;
|
||||
bool flag = _scrollEnd == 2;
|
||||
if (!flag) {
|
||||
calcPlayer();
|
||||
flag = (_vm->_screen->_clipWidth - _playerX - _vm->_screen->_scaleTable1[_scrollConst] -
|
||||
_vm->_player->_scrollThreshold) > 0;
|
||||
}
|
||||
if (flag) {
|
||||
walkOffset = _walkOffUR[_frame - _diagDownWalkMin].x;
|
||||
tempL = _rawPlayerLow.x + _vm->_screen->_scaleTable2[walkOffset];
|
||||
_rawTempL = (byte)tempL;
|
||||
_rawXTemp = _rawPlayer.x + _vm->_screen->_scaleTable1[walkOffset] +
|
||||
(tempL >= 0x100 ? 1 : 0);
|
||||
} else {
|
||||
_rawXTemp = _rawPlayer.x + _vm->_screen->_scaleTable1[_scrollConst];
|
||||
}
|
||||
|
||||
walkOffset = _walkOffDR[_frame - _diagDownWalkMin].y;
|
||||
tempL = _rawPlayerLow.y + _vm->_screen->_scaleTable2[walkOffset];
|
||||
_rawYTempL = (byte)tempL;
|
||||
_rawYTemp = _rawPlayer.y + _vm->_screen->_scaleTable1[walkOffset] +
|
||||
(tempL >= 0x100 ? 1 : 0);
|
||||
|
||||
if (_vm->_room->codeWalls()) {
|
||||
plotCom2();
|
||||
} else {
|
||||
_rawPlayer.x = _rawXTemp;
|
||||
_rawPlayer.y = _rawYTemp;
|
||||
_rawPlayerLow.x = _rawTempL;
|
||||
_rawPlayerLow.y = _rawYTempL;
|
||||
|
||||
calcManScale();
|
||||
|
||||
if (_vm->_currentMan != 3 && (_frame == 1 || _frame == 5))
|
||||
_vm->_sound->playSound(0);
|
||||
|
||||
++_frame;
|
||||
if (_frame > _diagDownWalkMax)
|
||||
_frame = _diagDownWalkMin;
|
||||
|
||||
plotCom(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::checkMove() {
|
||||
if (_playerMove) {
|
||||
if (_xFlag == 0 && _yFlag == 0) {
|
||||
int xp = (_playerOffset.x / 2) + _rawPlayer.x - _moveTo.x;
|
||||
if (xp < 0)
|
||||
xp = -xp;
|
||||
int yp = _rawPlayer.y - _moveTo.y;
|
||||
if (yp < 0)
|
||||
yp = -yp;
|
||||
|
||||
if (xp >= yp)
|
||||
_xFlag = 1;
|
||||
else
|
||||
_yFlag = 1;
|
||||
}
|
||||
|
||||
if (_yFlag == 1) {
|
||||
int yd = _rawPlayer.y - _moveTo.y;
|
||||
if ((yd >= 0 && yd <= _upDelta) || (yd < 0 && -yd <= _upDelta)) {
|
||||
++_yFlag;
|
||||
if (_xFlag) {
|
||||
_playerMove = false;
|
||||
_xFlag = _yFlag = 0;
|
||||
} else {
|
||||
++_xFlag;
|
||||
}
|
||||
} else {
|
||||
if (yd >= 0)
|
||||
walkUp();
|
||||
else
|
||||
walkDown();
|
||||
|
||||
if (_collideFlag) {
|
||||
_playerMove = false;
|
||||
_xFlag = _yFlag = 0;
|
||||
}
|
||||
}
|
||||
} else if (_xFlag == 1) {
|
||||
int xd = (_playerOffset.x / 2) + _rawPlayer.x - _moveTo.x;
|
||||
if ((xd >= 0 && xd <= -_leftDelta) || (xd < 0 && -xd <= -_leftDelta)) {
|
||||
++_xFlag;
|
||||
|
||||
if (_yFlag) {
|
||||
_playerMove = false;
|
||||
_xFlag = _yFlag = 0;
|
||||
}
|
||||
} else {
|
||||
if (xd >= 0)
|
||||
walkLeft();
|
||||
else
|
||||
walkRight();
|
||||
|
||||
if (_collideFlag) {
|
||||
_playerMove = false;
|
||||
_xFlag = _yFlag = 0;
|
||||
}
|
||||
}
|
||||
} else if (!_yFlag) {
|
||||
++_yFlag;
|
||||
} else {
|
||||
_playerMove = false;
|
||||
_xFlag = _yFlag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
plotCom3();
|
||||
}
|
||||
|
||||
void Player::plotCom(int flags) {
|
||||
_flags &= ~IMGFLAG_BACKWARDS;
|
||||
_flags &= ~IMGFLAG_UNSCALED;
|
||||
_flags |= flags;
|
||||
|
||||
plotCom3();
|
||||
}
|
||||
|
||||
void Player::plotCom0() {
|
||||
plotCom(_vm->getGameID() == kGameAmazon ? 0 : IMGFLAG_BACKWARDS);
|
||||
}
|
||||
|
||||
void Player::plotCom1() {
|
||||
plotCom(_vm->getGameID() == kGameAmazon ? IMGFLAG_BACKWARDS : 0);
|
||||
}
|
||||
|
||||
void Player::plotCom2() {
|
||||
// WORKAROUND: Amazon has at least one cutscene with the player not properly turned off
|
||||
if (!_playerOff && _spritesPtr != nullptr) {
|
||||
ImageEntry ie = *this;
|
||||
if (!isMMHover()) {
|
||||
_vm->_images.addToList(ie);
|
||||
} else if (_vm->_objectsTable[23]) {
|
||||
// MM player on hoverboard
|
||||
ie._spritesPtr = _vm->_objectsTable[23];
|
||||
ie._frameNumber = 13;
|
||||
_vm->_images.addToList(ie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::plotCom3() {
|
||||
// Update the base ImageEntry fields for the player
|
||||
_position.x = _rawPlayer.x;
|
||||
_position.y = _rawPlayer.y - _playerOffset.y;
|
||||
_offsetY = _playerOffset.y;
|
||||
_spritesPtr = _playerSprites;
|
||||
_frameNumber = _frame;
|
||||
|
||||
plotCom2();
|
||||
}
|
||||
|
||||
void Player::checkScrollUp() {
|
||||
if ((_playerDirection == DOWNRIGHT || _playerDirection == DOWNLEFT ||
|
||||
_playerDirection == DOWN) && (_vm->_screen->_clipHeight -
|
||||
_playerY - _scrollThreshold) <= 0) {
|
||||
// Scroll up
|
||||
if (scrollUp()) {
|
||||
_scrollEnd = 4;
|
||||
_vm->_scrollY &= TILE_HEIGHT;
|
||||
_scrollFlag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::checkScroll() {
|
||||
_scrollFlag = false;
|
||||
if (_playerDirection == NONE)
|
||||
return;
|
||||
|
||||
calcPlayer();
|
||||
|
||||
if ((_playerDirection == UPLEFT || _playerDirection == DOWNLEFT ||
|
||||
_playerDirection == LEFT) && _playerX <= _scrollThreshold) {
|
||||
// Scroll right
|
||||
if (!scrollRight()) {
|
||||
if (_playerDirection == DOWNLEFT)
|
||||
checkScrollUp();
|
||||
|
||||
return;
|
||||
}
|
||||
} else if ((_playerDirection == UPRIGHT || _playerDirection == DOWNRIGHT ||
|
||||
_playerDirection == RIGHT) && (_vm->_screen->_clipWidth -
|
||||
_playerX - _scrollThreshold) <= 0) {
|
||||
// Scroll left
|
||||
if (!scrollLeft()) {
|
||||
if (_playerDirection == DOWNRIGHT)
|
||||
checkScrollUp();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((_playerDirection == UPRIGHT || _playerDirection == UPLEFT ||
|
||||
_playerDirection == UP) && _playerY <= _scrollThreshold) {
|
||||
scrollDown();
|
||||
} else {
|
||||
checkScrollUp();
|
||||
}
|
||||
}
|
||||
|
||||
bool Player::scrollUp(int forcedAmount) {
|
||||
if (forcedAmount == -1)
|
||||
_scrollAmount = -(_vm->_screen->_clipHeight - _playerY - _scrollThreshold);
|
||||
else
|
||||
_scrollAmount = forcedAmount;
|
||||
|
||||
if ((_vm->_scrollRow + _vm->_screen->_vWindowHeight) >=
|
||||
_vm->_room->_playFieldHeight) {
|
||||
return true;
|
||||
}
|
||||
|
||||
_scrollFlag = true;
|
||||
_vm->_scrollY = _vm->_scrollY + _scrollAmount;
|
||||
|
||||
while (_vm->_scrollY >= TILE_HEIGHT && !_vm->shouldQuit()) {
|
||||
_vm->_scrollY -= TILE_HEIGHT;
|
||||
++_vm->_scrollRow;
|
||||
_vm->_buffer1.moveBufferUp();
|
||||
|
||||
_vm->_room->buildRow(_vm->_scrollRow + _vm->_screen->_vWindowHeight,
|
||||
_vm->_screen->_vWindowLinesTall);
|
||||
|
||||
if ((_vm->_scrollRow + _vm->_screen->_vWindowHeight) >=
|
||||
_vm->_room->_playFieldHeight)
|
||||
return true;
|
||||
|
||||
if (_vm->_scrollY <= TILE_HEIGHT)
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Player::scrollDown(int forcedAmount) {
|
||||
if (forcedAmount == -1)
|
||||
_scrollAmount = -(_playerY - _scrollThreshold);
|
||||
else
|
||||
_scrollAmount = forcedAmount;
|
||||
|
||||
_scrollFlag = true;
|
||||
_vm->_scrollY -= _scrollAmount;
|
||||
if (_vm->_scrollY >= 0)
|
||||
return true;
|
||||
|
||||
do {
|
||||
_vm->_scrollY += TILE_HEIGHT;
|
||||
if (--_vm->_scrollRow < 0)
|
||||
break;
|
||||
|
||||
_vm->_buffer1.moveBufferDown();
|
||||
_vm->_room->buildRow(_vm->_scrollRow, 0);
|
||||
|
||||
if (_vm->_scrollY >= 0)
|
||||
return false;
|
||||
} while (!_vm->shouldQuit());
|
||||
|
||||
_scrollEnd = 3;
|
||||
_vm->_scrollY = 0;
|
||||
_vm->_scrollRow = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Player::scrollLeft(int forcedAmount) {
|
||||
Screen &screen = *_vm->_screen;
|
||||
if (forcedAmount == -1)
|
||||
_scrollAmount = -(_vm->_screen->_clipWidth - _playerX - _scrollThreshold);
|
||||
else
|
||||
_scrollAmount = forcedAmount;
|
||||
|
||||
if ((_vm->_scrollCol + screen._vWindowWidth) == _vm->_room->_playFieldWidth) {
|
||||
_scrollEnd = 2;
|
||||
_vm->_scrollX = 0;
|
||||
_scrollFlag = true;
|
||||
return true;
|
||||
} else {
|
||||
_scrollFlag = true;
|
||||
_vm->_scrollX += _scrollAmount;
|
||||
|
||||
do {
|
||||
if (_vm->_scrollX < TILE_WIDTH)
|
||||
return true;
|
||||
|
||||
_vm->_scrollX -= TILE_WIDTH;
|
||||
++_vm->_scrollCol;
|
||||
_vm->_buffer1.moveBufferLeft();
|
||||
_vm->_room->buildColumn(_vm->_scrollCol + screen._vWindowWidth,
|
||||
screen._vWindowBytesWide);
|
||||
} while (!_vm->shouldQuit() && (_vm->_scrollX >= TILE_WIDTH));
|
||||
|
||||
return (_playerDirection == UPRIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
bool Player::scrollRight(int forcedAmount) {
|
||||
if (forcedAmount == -1)
|
||||
_scrollAmount = -(_playerX - _scrollThreshold);
|
||||
else
|
||||
_scrollAmount = forcedAmount;
|
||||
|
||||
_scrollFlag = true;
|
||||
_vm->_scrollX -= _scrollAmount;
|
||||
|
||||
if (_vm->_scrollX < 0) {
|
||||
do {
|
||||
_vm->_scrollX += TILE_WIDTH;
|
||||
if (--_vm->_scrollCol < 0) {
|
||||
_scrollEnd = 1;
|
||||
_vm->_scrollX = 0;
|
||||
_vm->_scrollCol = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
_vm->_buffer1.moveBufferRight();
|
||||
_vm->_room->buildColumn(_vm->_scrollCol, 0);
|
||||
} while (!_vm->shouldQuit() && (_vm->_scrollX < 0));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Player::synchronize(Common::Serializer &s) {
|
||||
s.syncAsUint16LE(_roomNumber);
|
||||
s.syncAsSint16LE(_rawPlayerLow.x);
|
||||
s.syncAsSint16LE(_rawPlayer.x);
|
||||
s.syncAsSint16LE(_rawPlayerLow.y);
|
||||
s.syncAsSint16LE(_rawPlayer.y);
|
||||
}
|
||||
|
||||
} // End of namespace Access
|
||||
Reference in New Issue
Block a user