scummvm/engines/gob/map_v2.cpp
Sven Hesse 370107c953 GOB: Remove a useless call to Variables::getAddressOff8()
This is a left-over vestige of when the gob engine recorded the size
of each variable currently in use, because it byte-swapped all
variables on save/load depending on the machine ScummVM ran on.

The gob engine doesn't do that all anymore (instead, the variables are
always stored in the endianness of the original game), so
getAddressOff8() doesn't store "this is an 8-bit variable" anymore,
making the call a NOP.

This fixes Coverity Scan issue #1267142.
2015-08-03 15:56:43 +02:00

286 lines
7.5 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/stream.h"
#include "gob/gob.h"
#include "gob/map.h"
#include "gob/global.h"
#include "gob/goblin.h"
#include "gob/inter.h"
#include "gob/game.h"
#include "gob/script.h"
#include "gob/resources.h"
#include "gob/mult.h"
namespace Gob {
Map_v2::Map_v2(GobEngine *vm) : Map_v1(vm) {
_screenHeight = 200;
}
Map_v2::~Map_v2() {
_passMap = 0;
}
void Map_v2::loadMapObjects(const char *avjFile) {
uint8 wayPointsCount;
uint16 var;
int16 id;
int16 mapWidth, mapHeight;
int16 tmp;
byte *variables;
uint32 tmpPos;
uint32 passPos;
var = _vm->_game->_script->readVarIndex();
variables = _vm->_inter->_variables->getAddressOff8(var);
id = _vm->_game->_script->readInt16();
if (((uint16) id) >= 65520) {
switch ((uint16) id) {
case 65530:
for (int i = 0; i < _mapWidth * _mapHeight; i++)
_passMap[i] -= READ_VARO_UINT8(var + i);
break;
case 65531:
for (int i = 0; i < _mapWidth * _mapHeight; i++)
_passMap[i] += READ_VARO_UINT8(var + i);
break;
case 65532:
for (int i = 0; i < _mapWidth * _mapHeight; i++)
WRITE_VARO_UINT8(var + i, 0x00);
break;
case 65533: {
int index = READ_VARO_UINT16(var);
// _vm->_mult->_objects[index].field_6E = 0;
// _vm->_mult->_objects[index].field_6A = variables;
warning("Map_v2::loadMapObjects(): ID == 65533 (%d)", index);
break;
}
case 65534:
_tilesWidth = READ_VARO_UINT8(var);
_tilesHeight = READ_VARO_UINT8(var + 1);
_mapWidth = READ_VARO_UINT8(var + 2);
_mapHeight = READ_VARO_UINT8(var + 3);
_mapUnknownBool = READ_VARO_UINT8(var + 4) ? true : false;
if (_mapUnknownBool)
warning("Map_v2::loadMapObjects(): _mapUnknownBool == true");
break;
case 65535:
_passMap = (int8 *)_vm->_inter->_variables->getAddressOff8(var);
break;
default:
warning("Map_v2::loadMapObjects(): ID == %d", (uint16) id);
break;
}
return;
}
Resource *resource = _vm->_game->_resources->getResource(id);
if (!resource)
return;
Common::SeekableReadStream &mapData = *resource->stream();
_mapVersion = mapData.readByte();
if (_mapVersion == 4) {
_screenWidth = 640;
_screenHeight = 400;
} else if (_mapVersion == 3) {
_passWidth = 65;
_screenWidth = 640;
_screenHeight = 200;
} else {
_passWidth = 40;
_screenWidth = 320;
_screenHeight = 200;
}
_wayPointCount = mapData.readByte();
_tilesWidth = mapData.readSint16LE();
_tilesHeight = mapData.readSint16LE();
_bigTiles = !(_tilesHeight & 0xFF00);
_tilesHeight &= 0xFF;
if (_mapVersion == 4) {
_screenWidth = mapData.readSint16LE();
_screenHeight = mapData.readSint16LE();
}
_mapWidth = _screenWidth / _tilesWidth;
_mapHeight = _screenHeight / _tilesHeight;
passPos = mapData.pos();
mapData.skip(_mapWidth * _mapHeight);
if (resource->getData()[0] == 1)
wayPointsCount = _wayPointCount = 40;
else
wayPointsCount = _wayPointCount == 0 ? 1 : _wayPointCount;
delete[] _wayPoints;
_wayPoints = new WayPoint[wayPointsCount];
for (int i = 0; i < _wayPointCount; i++) {
_wayPoints[i].x = mapData.readSByte();
_wayPoints[i].y = mapData.readSByte();
_wayPoints[i].notWalkable = mapData.readSByte();
}
if (_mapVersion == 4) {
_mapWidth = VAR(17);
_passWidth = _mapWidth;
}
// In the original asm, this writes byte-wise into the variables-array
tmpPos = mapData.pos();
mapData.seek(passPos);
if ((variables != 0) &&
(variables != _vm->_inter->_variables->getAddressOff8(0))) {
_passMap = (int8 *)variables;
mapHeight = _screenHeight / _tilesHeight;
mapWidth = _screenWidth / _tilesWidth;
for (int i = 0; i < mapHeight; i++)
for (int j = 0; j < mapWidth; j++)
setPass(j, i, mapData.readSByte());
}
mapData.seek(tmpPos);
tmp = mapData.readSint16LE();
mapData.skip(tmp * 14);
tmp = mapData.readSint16LE();
mapData.skip(tmp * 14 + 28);
tmp = mapData.readSint16LE();
mapData.skip(tmp * 14);
_vm->_goblin->_gobsCount = tmp;
for (int i = 0; i < _vm->_goblin->_gobsCount; i++)
loadGoblinStates(mapData, i);
_vm->_goblin->_soundSlotsCount = _vm->_game->_script->readInt16();
for (int i = 0; i < _vm->_goblin->_soundSlotsCount; i++)
_vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1);
delete resource;
}
void Map_v2::loadGoblinStates(Common::SeekableReadStream &data, int index) {
Mult::Mult_GobState *statesPtr;
Mult::Mult_GobState *gobState;
int8 indices[102];
uint8 statesCount;
uint8 dataCount;
int16 state;
uint32 tmpPos;
memset(indices, -1, 101);
_vm->_mult->_objects[index].goblinStates = new Mult::Mult_GobState*[101];
memset(_vm->_mult->_objects[index].goblinStates, 0,
101 * sizeof(Mult::Mult_GobState *));
data.read(indices, 100);
tmpPos = data.pos();
statesCount = 0;
for (int i = 0; i < 100; i++) {
if (indices[i] != -1) {
statesCount++;
data.skip(4);
dataCount = data.readByte();
statesCount += dataCount;
data.skip(dataCount * 9);
}
}
data.seek(tmpPos);
statesPtr = new Mult::Mult_GobState[statesCount];
_vm->_mult->_objects[index].goblinStates[0] = statesPtr;
for (int i = 0; i < 100; i++) {
state = indices[i];
if (state != -1) {
_vm->_mult->_objects[index].goblinStates[state] = statesPtr++;
gobState = _vm->_mult->_objects[index].goblinStates[state];
gobState[0].animation = data.readSint16LE();
gobState[0].layer = data.readSint16LE();
dataCount = data.readByte();
gobState[0].dataCount = dataCount;
for (uint8 j = 1; j <= dataCount; j++) {
data.skip(1);
gobState[j].sndItem = data.readSByte();
data.skip(1);
gobState[j].sndFrame = data.readByte();
data.skip(1);
gobState[j].freq = data.readSint16LE();
gobState[j].repCount = data.readSByte();
gobState[j].speaker = data.readByte();
statesPtr++;
}
}
}
}
void Map_v2::findNearestToGob(Mult::Mult_Object *obj) {
int16 wayPoint = findNearestWayPoint(obj->goblinX, obj->goblinY);
if (wayPoint != -1)
obj->nearestWayPoint = wayPoint;
}
void Map_v2::findNearestToDest(Mult::Mult_Object *obj) {
int16 wayPoint = findNearestWayPoint(obj->destX, obj->destY);
if (wayPoint != -1)
obj->nearestDest = wayPoint;
}
void Map_v2::optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y) {
if (!_wayPoints)
return;
if (obj->nearestWayPoint < obj->nearestDest) {
for (int i = obj->nearestWayPoint; i <= obj->nearestDest; i++) {
if (checkDirectPath(obj, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
obj->nearestWayPoint = i;
}
} else {
for (int i = obj->nearestWayPoint; i >= obj->nearestDest; i--) {
if (_wayPoints[i].notWalkable == 1)
break;
if (checkDirectPath(obj, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
obj->nearestWayPoint = i;
}
}
}
} // End of namespace Gob