mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-30 15:31:59 +00:00
129988d0e9
These are flagged by GCC if -Wswitch-default is enabled.
639 lines
20 KiB
C++
639 lines
20 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 "illusions/illusions.h"
|
|
#include "illusions/resources/backgroundresource.h"
|
|
#include "illusions/actor.h"
|
|
#include "illusions/camera.h"
|
|
#include "illusions/dictionary.h"
|
|
#include "illusions/resources/actorresource.h"
|
|
#include "illusions/screen.h"
|
|
#include "illusions/sequenceopcodes.h"
|
|
#include "common/str.h"
|
|
|
|
namespace Illusions {
|
|
|
|
// BackgroundResourceLoader
|
|
|
|
void BackgroundResourceLoader::load(Resource *resource) {
|
|
resource->_instance = _vm->_backgroundInstances->createBackgroundInstance(resource);
|
|
}
|
|
|
|
bool BackgroundResourceLoader::isFlag(int flag) {
|
|
return
|
|
flag == kRlfLoadFile;
|
|
}
|
|
|
|
// TileMap
|
|
|
|
void TileMap::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
|
_width = stream.readSint16LE();
|
|
_height = stream.readSint16LE();
|
|
stream.skip(4); // Unknown
|
|
uint32 mapOffs = stream.pos();
|
|
_map = dataStart + mapOffs;
|
|
debug(0, "TileMap::load() _width: %d; _height: %d",
|
|
_width, _height);
|
|
}
|
|
|
|
// BgInfo
|
|
|
|
void BgInfo::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
|
_flags = stream.readUint32LE();
|
|
uint16 unknown = stream.readUint16LE(); // TODO Unknown
|
|
_priorityBase = stream.readSint16LE();
|
|
_surfInfo.load(stream);
|
|
loadPoint(stream, _panPoint);
|
|
uint32 tileMapOffs = stream.readUint32LE();
|
|
uint32 tilePixelsOffs = stream.readUint32LE();
|
|
stream.seek(tileMapOffs);
|
|
_tileMap.load(dataStart, stream);
|
|
_tilePixels = dataStart + tilePixelsOffs;
|
|
debug(0, "BgInfo::load() _flags: %08X; unknown: %04X; _priorityBase: %d; tileMapOffs: %08X; tilePixelsOffs: %08X",
|
|
_flags, unknown, _priorityBase, tileMapOffs, tilePixelsOffs);
|
|
}
|
|
|
|
// PriorityLayer
|
|
|
|
void PriorityLayer::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
|
_width = stream.readUint16LE();
|
|
_height = stream.readUint16LE();
|
|
uint32 mapOffs = stream.readUint32LE();
|
|
uint32 valuesOffs = stream.readUint32LE();
|
|
_map = dataStart + mapOffs;
|
|
_mapWidth = READ_LE_UINT16(_map + 0);
|
|
_mapHeight = READ_LE_UINT16(_map + 2);
|
|
_map += 8;
|
|
_values = dataStart + valuesOffs;
|
|
debug(0, "PriorityLayer::load() _width: %d; _height: %d; mapOffs: %08X; valuesOffs: %08X; _mapWidth: %d; _mapHeight: %d",
|
|
_width, _height, mapOffs, valuesOffs, _mapWidth, _mapHeight);
|
|
}
|
|
|
|
int PriorityLayer::getPriority(Common::Point pos) {
|
|
pos.x = CLIP<int16>(pos.x, 0, _width - 1);
|
|
pos.y = CLIP<int16>(pos.y, 0, _height - 1);
|
|
const int16 tx = pos.x / 32, sx = pos.x % 32;
|
|
const int16 ty = pos.y / 8, sy = pos.y % 8;
|
|
uint16 mapIndex = READ_LE_UINT16(_map + 2 * (tx + ty * _mapWidth)) - 1;
|
|
return _values[mapIndex * 32 * 8 + sx + sy * 32];
|
|
}
|
|
|
|
// ScaleLayer
|
|
|
|
void ScaleLayer::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
|
_height = stream.readUint16LE();
|
|
stream.skip(2);
|
|
uint32 valuesOffs = stream.readUint32LE();
|
|
_values = dataStart + valuesOffs;
|
|
debug(0, "ScaleLayer::load() _height: %d; valuesOffs: %08X",
|
|
_height, valuesOffs);
|
|
}
|
|
|
|
int ScaleLayer::getScale(Common::Point pos) {
|
|
pos.y = CLIP<int16>(pos.y, 0, _height - 1);
|
|
return _values[pos.y];
|
|
}
|
|
|
|
// RegionLayer
|
|
|
|
void RegionLayer::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
|
_unk = stream.readUint32LE();
|
|
uint32 regionSequenceIdsOffs = stream.readUint32LE();
|
|
_width = stream.readUint16LE();
|
|
_height = stream.readUint16LE();
|
|
uint32 mapOffs = stream.readUint32LE();
|
|
uint32 valuesOffs = stream.readUint32LE();
|
|
_regionSequenceIds = dataStart + regionSequenceIdsOffs;
|
|
_map = dataStart + mapOffs;
|
|
_values = dataStart + valuesOffs;
|
|
_mapWidth = READ_LE_UINT16(_map + 0);
|
|
_mapHeight = READ_LE_UINT16(_map + 2);
|
|
_map += 8;
|
|
debug(1, "RegionLayer::load() %d; regionSequenceIdsOffs: %08X; _width: %d; _height: %d; mapOffs: %08X; valuesOffs: %08X",
|
|
_unk, regionSequenceIdsOffs, _width, _height, mapOffs, valuesOffs);
|
|
}
|
|
|
|
int RegionLayer::getRegionIndex(Common::Point pos) {
|
|
pos.x = CLIP<int16>(pos.x, 0, _width - 1);
|
|
pos.y = CLIP<int16>(pos.y, 0, _height - 1);
|
|
const int16 tx = pos.x / 32, sx = pos.x % 32;
|
|
const int16 ty = pos.y / 8, sy = pos.y % 8;
|
|
uint16 mapIndex = READ_LE_UINT16(_map + 2 * (tx + ty * _mapWidth)) - 1;
|
|
return _values[mapIndex * 32 * 8 + sx + sy * 32];
|
|
}
|
|
|
|
uint32 RegionLayer::getRegionSequenceId(int regionIndex) {
|
|
return READ_LE_UINT32(_regionSequenceIds + 4 * regionIndex);
|
|
}
|
|
|
|
// Palette
|
|
|
|
void Palette::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
|
_count = stream.readUint16LE();
|
|
_unk = stream.readUint16LE();
|
|
uint32 paletteOffs = stream.readUint32LE();
|
|
_palette = dataStart + paletteOffs;
|
|
}
|
|
|
|
// BackgroundObject
|
|
|
|
void BackgroundObject::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
|
_objectId = stream.readUint32LE();
|
|
_flags = stream.readUint16LE();
|
|
_priority = stream.readUint16LE();
|
|
uint32 pointsConfigOffs = stream.readUint32LE();
|
|
_pointsConfig = dataStart + pointsConfigOffs;
|
|
debug(0, "BackgroundObject::load() _objectId: %08X; _flags: %04X; _priority: %d; pointsConfigOffs: %08X",
|
|
_objectId, _flags, _priority, pointsConfigOffs);
|
|
}
|
|
|
|
// PathWalkPoints
|
|
|
|
void PathWalkPoints::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
|
_points = new PointArray();
|
|
uint count = stream.readUint32LE();
|
|
uint32 pointsOffs = stream.readUint32LE();
|
|
_points->reserve(count);
|
|
stream.seek(pointsOffs);
|
|
for (uint i = 0; i < count; ++i) {
|
|
Common::Point pt;
|
|
loadPoint(stream, pt);
|
|
_points->push_back(pt);
|
|
}
|
|
debug(0, "PathWalkPoints::load() count: %d; pointsOffs: %08X",
|
|
count, pointsOffs);
|
|
}
|
|
|
|
// PathWalkRects
|
|
|
|
void PathWalkRects::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
|
_rects = new PathLines();
|
|
uint count = stream.readUint32LE();
|
|
uint32 rectsOffs = stream.readUint32LE();
|
|
_rects->reserve(count);
|
|
stream.seek(rectsOffs);
|
|
for (uint i = 0; i < count; ++i) {
|
|
PathLine rect;
|
|
loadPoint(stream, rect.p0);
|
|
loadPoint(stream, rect.p1);
|
|
_rects->push_back(rect);
|
|
}
|
|
debug(0, "PathWalkRects::load() count: %d; rectsOffs: %08X",
|
|
count, rectsOffs);
|
|
}
|
|
|
|
// BackgroundResource
|
|
|
|
BackgroundResource::BackgroundResource()
|
|
: _bgInfos(0), _scaleLayers(0), _priorityLayers(0), _regionLayers(0),
|
|
_regionSequences(0), _backgroundObjects(0), _pathWalkPoints(0),
|
|
_pathWalkRects(0), _palettes(0) {
|
|
}
|
|
|
|
BackgroundResource::~BackgroundResource() {
|
|
delete[] _bgInfos;
|
|
delete[] _scaleLayers;
|
|
delete[] _priorityLayers;
|
|
delete[] _regionLayers;
|
|
delete[] _regionSequences;
|
|
delete[] _backgroundObjects;
|
|
delete[] _pathWalkPoints;
|
|
delete[] _pathWalkRects;
|
|
delete[] _palettes;
|
|
}
|
|
|
|
void BackgroundResource::load(byte *data, uint32 dataSize) {
|
|
Common::MemoryReadStream stream(data, dataSize, DisposeAfterUse::NO);
|
|
|
|
stream.seek(8);
|
|
_paletteIndex = stream.readUint16LE();
|
|
|
|
// Load background pixels
|
|
stream.seek(0x0A);
|
|
_bgInfosCount = stream.readUint16LE();
|
|
_bgInfos = new BgInfo[_bgInfosCount];
|
|
stream.seek(0x20);
|
|
uint32 bgInfosOffs = stream.readUint32LE();
|
|
for (uint i = 0; i < _bgInfosCount; ++i) {
|
|
stream.seek(bgInfosOffs + i * 0x1C);
|
|
_bgInfos[i].load(data, stream);
|
|
}
|
|
|
|
// Load scale layers
|
|
stream.seek(0x10);
|
|
_scaleLayersCount = stream.readUint16LE();
|
|
_scaleLayers = new ScaleLayer[_scaleLayersCount];
|
|
stream.seek(0x2C);
|
|
uint32 scaleLayersOffs = stream.readUint32LE();
|
|
debug(0, "_scaleLayersCount: %d", _scaleLayersCount);
|
|
for (uint i = 0; i < _scaleLayersCount; ++i) {
|
|
stream.seek(scaleLayersOffs + i * 8);
|
|
_scaleLayers[i].load(data, stream);
|
|
}
|
|
|
|
// Load priority layers
|
|
stream.seek(0x14);
|
|
_priorityLayersCount = stream.readUint16LE();
|
|
_priorityLayers = new PriorityLayer[_priorityLayersCount];
|
|
stream.seek(0x34);
|
|
uint32 priorityLayersOffs = stream.readUint32LE();
|
|
debug(1, "_priorityLayersCount: %d", _priorityLayersCount);
|
|
for (uint i = 0; i < _priorityLayersCount; ++i) {
|
|
stream.seek(priorityLayersOffs + i * 12);
|
|
_priorityLayers[i].load(data, stream);
|
|
}
|
|
|
|
// Load region layers
|
|
stream.seek(0x16);
|
|
_regionLayersCount = stream.readUint16LE();
|
|
_regionLayers = new RegionLayer[_regionLayersCount];
|
|
stream.seek(0x38);
|
|
uint32 regionLayersOffs = stream.readUint32LE();
|
|
debug(1, "_regionLayersCount: %d", _regionLayersCount);
|
|
for (uint i = 0; i < _regionLayersCount; ++i) {
|
|
stream.seek(regionLayersOffs + i * 20);
|
|
_regionLayers[i].load(data, stream);
|
|
}
|
|
|
|
// Load region sequences
|
|
stream.seek(0x1E);
|
|
_regionSequencesCount = stream.readUint16LE();
|
|
_regionSequences = new Sequence[_regionSequencesCount];
|
|
stream.seek(0x48);
|
|
uint32 regionSequencesOffs = stream.readUint32LE();
|
|
stream.seek(regionSequencesOffs);
|
|
for (uint i = 0; i < _regionSequencesCount; ++i) {
|
|
_regionSequences[i].load(data, stream);
|
|
}
|
|
|
|
// Load background objects
|
|
stream.seek(0x1C);
|
|
_backgroundObjectsCount = stream.readUint16LE();
|
|
_backgroundObjects = new BackgroundObject[_backgroundObjectsCount];
|
|
stream.seek(0x44);
|
|
uint32 backgroundObjectsOffs = stream.readUint32LE();
|
|
debug(0, "_backgroundObjectsCount: %d", _backgroundObjectsCount);
|
|
for (uint i = 0; i < _backgroundObjectsCount; ++i) {
|
|
stream.seek(backgroundObjectsOffs + i * 12);
|
|
_backgroundObjects[i].load(data, stream);
|
|
}
|
|
|
|
// Load path walk points
|
|
stream.seek(0x0E);
|
|
_pathWalkPointsCount = stream.readUint16LE();
|
|
debug(1, "_pathWalkPointsCount: %d", _pathWalkPointsCount);
|
|
_pathWalkPoints = new PathWalkPoints[_pathWalkPointsCount];
|
|
stream.seek(0x28);
|
|
uint32 pathWalkPointsOffs = stream.readUint32LE();
|
|
for (uint i = 0; i < _pathWalkPointsCount; ++i) {
|
|
stream.seek(pathWalkPointsOffs + i * 8);
|
|
_pathWalkPoints[i].load(data, stream);
|
|
}
|
|
|
|
// Load path walk rects
|
|
stream.seek(0x12);
|
|
_pathWalkRectsCount = stream.readUint16LE();
|
|
debug(1, "_pathWalkRectsCount: %d", _pathWalkRectsCount);
|
|
_pathWalkRects = new PathWalkRects[_pathWalkRectsCount];
|
|
stream.seek(0x30);
|
|
uint32 pathWalkRectsOffs = stream.readUint32LE();
|
|
for (uint i = 0; i < _pathWalkRectsCount; ++i) {
|
|
stream.seek(pathWalkRectsOffs + i * 8);
|
|
_pathWalkRects[i].load(data, stream);
|
|
}
|
|
|
|
// Load named points
|
|
stream.seek(0xC);
|
|
uint namedPointsCount = stream.readUint16LE();
|
|
stream.seek(0x24);
|
|
uint32 namedPointsOffs = stream.readUint32LE();
|
|
stream.seek(namedPointsOffs);
|
|
_namedPoints.load(namedPointsCount, stream);
|
|
|
|
// Load palettes
|
|
stream.seek(0x18);
|
|
_palettesCount = stream.readUint16LE();
|
|
_palettes = new Palette[_palettesCount];
|
|
stream.seek(0x3C);
|
|
uint32 palettesOffs = stream.readUint32LE();
|
|
debug(0, "_palettesCount: %d", _palettesCount);
|
|
for (uint i = 0; i < _palettesCount; ++i) {
|
|
stream.seek(palettesOffs + i * 8);
|
|
_palettes[i].load(data, stream);
|
|
}
|
|
|
|
}
|
|
|
|
int BackgroundResource::findMasterBgIndex() {
|
|
int index = 1;
|
|
while (!(_bgInfos[index - 1]._flags & 1)) { // TODO check if this is correct
|
|
++index;
|
|
}
|
|
return index;
|
|
}
|
|
|
|
PriorityLayer *BackgroundResource::getPriorityLayer(uint index) {
|
|
return &_priorityLayers[index];
|
|
}
|
|
|
|
ScaleLayer *BackgroundResource::getScaleLayer(uint index) {
|
|
return &_scaleLayers[index];
|
|
}
|
|
|
|
RegionLayer *BackgroundResource::getRegionLayer(uint index) {
|
|
return &_regionLayers[index];
|
|
}
|
|
|
|
PathWalkPoints *BackgroundResource::getPathWalkPoints(uint index) {
|
|
return &_pathWalkPoints[index];
|
|
}
|
|
|
|
PathWalkRects *BackgroundResource::getPathWalkRects(uint index) {
|
|
return &_pathWalkRects[index];
|
|
}
|
|
|
|
Palette *BackgroundResource::getPalette(uint index) {
|
|
return &_palettes[index];
|
|
}
|
|
|
|
bool BackgroundResource::findNamedPoint(uint32 namedPointId, Common::Point &pt) {
|
|
return _namedPoints.findNamedPoint(namedPointId, pt);
|
|
}
|
|
|
|
// BackgroundInstance
|
|
|
|
BackgroundInstance::BackgroundInstance(IllusionsEngine *vm)
|
|
: _vm(vm), _sceneId(0), _pauseCtr(0), _bgRes(0), _savedPalette(0) {
|
|
}
|
|
|
|
void BackgroundInstance::load(Resource *resource) {
|
|
debug(1, "BackgroundResourceLoader::load() Loading background %08X from %s...", resource->_resId, resource->_filename.c_str());
|
|
|
|
BackgroundResource *backgroundResource = new BackgroundResource();
|
|
backgroundResource->load(resource->_data, resource->_dataSize);
|
|
|
|
_bgRes = backgroundResource;
|
|
_sceneId = resource->_sceneId;
|
|
initSurface();
|
|
|
|
// Insert background objects
|
|
for (uint i = 0; i < backgroundResource->_backgroundObjectsCount; ++i) {
|
|
_vm->_controls->placeBackgroundObject(&backgroundResource->_backgroundObjects[i]);
|
|
}
|
|
|
|
registerResources();
|
|
|
|
_vm->clearFader();
|
|
|
|
int index = _bgRes->findMasterBgIndex();
|
|
_vm->_camera->set(_bgRes->_bgInfos[index - 1]._panPoint, _bgRes->_bgInfos[index - 1]._surfInfo._dimensions);
|
|
|
|
if (_bgRes->_palettesCount > 0) {
|
|
Palette *palette = _bgRes->getPalette(_bgRes->_paletteIndex - 1);
|
|
_vm->_screenPalette->setPalette(palette->_palette, 1, palette->_count);
|
|
}
|
|
|
|
}
|
|
|
|
void BackgroundInstance::unload() {
|
|
debug(1, "BackgroundInstance::unload()");
|
|
freeSurface();
|
|
unregisterResources();
|
|
delete _bgRes;
|
|
_vm->_backgroundInstances->removeBackgroundInstance(this);
|
|
_vm->setDefaultTextCoords();
|
|
}
|
|
|
|
void BackgroundInstance::pause() {
|
|
++_pauseCtr;
|
|
if (_pauseCtr <= 1) {
|
|
unregisterResources();
|
|
_vm->setDefaultTextCoords();
|
|
_vm->_camera->getActiveState(_savedCameraState);
|
|
_savedPalette = new byte[1024];
|
|
_vm->_screenPalette->getPalette(_savedPalette);
|
|
freeSurface();
|
|
}
|
|
}
|
|
|
|
void BackgroundInstance::unpause() {
|
|
--_pauseCtr;
|
|
if (_pauseCtr <= 0) {
|
|
registerResources();
|
|
initSurface();
|
|
_vm->_screenPalette->setPalette(_savedPalette, 1, 256);
|
|
delete[] _savedPalette;
|
|
_savedPalette = 0;
|
|
_vm->clearFader();
|
|
_vm->_camera->setActiveState(_savedCameraState);
|
|
_vm->_backgroundInstances->refreshPan();
|
|
}
|
|
}
|
|
|
|
void BackgroundInstance::registerResources() {
|
|
for (uint i = 0; i < _bgRes->_regionSequencesCount; ++i) {
|
|
Sequence *sequence = &_bgRes->_regionSequences[i];
|
|
_vm->_dict->addSequence(sequence->_sequenceId, sequence);
|
|
}
|
|
}
|
|
|
|
void BackgroundInstance::unregisterResources() {
|
|
for (uint i = 0; i < _bgRes->_regionSequencesCount; ++i) {
|
|
Sequence *sequence = &_bgRes->_regionSequences[i];
|
|
_vm->_dict->removeSequence(sequence->_sequenceId);
|
|
}
|
|
}
|
|
|
|
void BackgroundInstance::initSurface() {
|
|
for (uint i = 0; i < kMaxBackgroundItemSurfaces; ++i) {
|
|
_surfaces[i] = 0;
|
|
}
|
|
for (uint i = 0; i < _bgRes->_bgInfosCount; ++i) {
|
|
BgInfo *bgInfo = &_bgRes->_bgInfos[i];
|
|
_panPoints[i] = bgInfo->_panPoint;
|
|
_surfaces[i] = _vm->_screen->allocSurface(bgInfo->_surfInfo);
|
|
drawTiles(_surfaces[i], bgInfo->_tileMap, bgInfo->_tilePixels);
|
|
#if 0
|
|
if (_bgRes->_pathWalkRectsCount > 0) {
|
|
PathLines *pl = _bgRes->_pathWalkRects->_rects;
|
|
for (int j=0; j < pl->size(); j++) {
|
|
PathLine pathLine = (*pl)[j];
|
|
debug(0, "walk path rect line[%d]. (%d,%d)->(%d,%d)", j, pathLine.p0.x, pathLine.p0.y, pathLine.p1.x, pathLine.p1.y);
|
|
_surfaces[i]->drawLine(pathLine.p0.x, pathLine.p0.y, pathLine.p1.x, pathLine.p1.y, 5);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void BackgroundInstance::freeSurface() {
|
|
for (uint i = 0; i < _bgRes->_bgInfosCount; ++i) {
|
|
if (_surfaces[i]) {
|
|
_surfaces[i]->free();
|
|
delete _surfaces[i];
|
|
_surfaces[i] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void BackgroundInstance::drawTiles(Graphics::Surface *surface, TileMap &tileMap, byte *tilePixels) {
|
|
switch (_vm->getGameId()) {
|
|
case kGameIdDuckman:
|
|
drawTiles8(surface, tileMap, tilePixels);
|
|
break;
|
|
case kGameIdBBDOU:
|
|
drawTiles16(surface, tileMap, tilePixels);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void BackgroundInstance::drawTiles8(Graphics::Surface *surface, TileMap &tileMap, byte *tilePixels) {
|
|
const int kTileWidth = 32;
|
|
const int kTileHeight = 8;
|
|
const int kTileSize = kTileWidth * kTileHeight;
|
|
uint tileMapIndex = 0;
|
|
for (int tileY = 0; tileY < tileMap._height; ++tileY) {
|
|
int tileDestY = tileY * kTileHeight;
|
|
int tileDestH = MIN(kTileHeight, surface->h - tileDestY);
|
|
for (int tileX = 0; tileX < tileMap._width; ++tileX) {
|
|
int tileDestX = tileX * kTileWidth;
|
|
int tileDestW = MIN(kTileWidth, surface->w - tileDestX);
|
|
uint16 tileIndex = READ_LE_UINT16(tileMap._map + 2 * tileMapIndex);
|
|
++tileMapIndex;
|
|
byte *src = tilePixels + (tileIndex - 1) * kTileSize;
|
|
byte *dst = (byte*)surface->getBasePtr(tileDestX, tileDestY);
|
|
for (int h = 0; h < tileDestH; ++h) {
|
|
memcpy(dst, src, tileDestW);
|
|
dst += surface->pitch;
|
|
src += kTileWidth;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void BackgroundInstance::drawTiles16(Graphics::Surface *surface, TileMap &tileMap, byte *tilePixels) {
|
|
const int kTileWidth = 32;
|
|
const int kTileHeight = 8;
|
|
const int kTileSize = kTileWidth * kTileHeight * 2;
|
|
uint tileMapIndex = 0;
|
|
for (int tileY = 0; tileY < tileMap._height; ++tileY) {
|
|
int tileDestY = tileY * kTileHeight;
|
|
int tileDestH = MIN(kTileHeight, surface->h - tileDestY);
|
|
for (int tileX = 0; tileX < tileMap._width; ++tileX) {
|
|
int tileDestX = tileX * kTileWidth;
|
|
int tileDestW = MIN(kTileWidth, surface->w - tileDestX);
|
|
uint16 tileIndex = READ_LE_UINT16(tileMap._map + 2 * tileMapIndex);
|
|
++tileMapIndex;
|
|
byte *src = tilePixels + (tileIndex - 1) * kTileSize;
|
|
byte *dst = (byte*)surface->getBasePtr(tileDestX, tileDestY);
|
|
for (int h = 0; h < tileDestH; ++h) {
|
|
for (int w = 0; w < tileDestW; ++w) {
|
|
uint16 pixel = READ_LE_UINT16(src + w * 2);
|
|
WRITE_LE_UINT16(dst + w * 2, pixel);
|
|
}
|
|
dst += surface->pitch;
|
|
src += kTileWidth * 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// BackgroundInstanceList
|
|
|
|
BackgroundInstanceList::BackgroundInstanceList(IllusionsEngine *vm)
|
|
: _vm(vm) {
|
|
}
|
|
|
|
BackgroundInstanceList::~BackgroundInstanceList() {
|
|
}
|
|
|
|
BackgroundInstance *BackgroundInstanceList::createBackgroundInstance(Resource *resource) {
|
|
BackgroundInstance *backgroundInstance = new BackgroundInstance(_vm);
|
|
backgroundInstance->load(resource);
|
|
_items.push_back(backgroundInstance);
|
|
return backgroundInstance;
|
|
}
|
|
|
|
void BackgroundInstanceList::removeBackgroundInstance(BackgroundInstance *backgroundInstance) {
|
|
_items.remove(backgroundInstance);
|
|
}
|
|
|
|
void BackgroundInstanceList::pauseBySceneId(uint32 sceneId) {
|
|
for (ItemsIterator it = _items.begin(); it != _items.end(); ++it) {
|
|
if ((*it)->_sceneId == sceneId)
|
|
(*it)->pause();
|
|
}
|
|
}
|
|
|
|
void BackgroundInstanceList::unpauseBySceneId(uint32 sceneId) {
|
|
for (ItemsIterator it = _items.begin(); it != _items.end(); ++it) {
|
|
if ((*it)->_sceneId == sceneId)
|
|
(*it)->unpause();
|
|
}
|
|
}
|
|
|
|
BackgroundInstance *BackgroundInstanceList::findActiveBackgroundInstance() {
|
|
for (ItemsIterator it = _items.begin(); it != _items.end(); ++it) {
|
|
if ((*it)->_pauseCtr == 0)
|
|
return (*it);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
BackgroundInstance *BackgroundInstanceList::findBackgroundByResource(BackgroundResource *backgroundResource) {
|
|
for (ItemsIterator it = _items.begin(); it != _items.end(); ++it) {
|
|
if ((*it)->_bgRes == backgroundResource)
|
|
return (*it);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
BackgroundResource *BackgroundInstanceList::getActiveBgResource() {
|
|
BackgroundInstance *background = findActiveBackgroundInstance();
|
|
if (background)
|
|
return background->_bgRes;
|
|
return 0;
|
|
}
|
|
|
|
WidthHeight BackgroundInstanceList::getMasterBgDimensions() {
|
|
BackgroundInstance *backgroundInstance = findActiveBackgroundInstance();
|
|
int16 index = backgroundInstance->_bgRes->findMasterBgIndex();
|
|
return backgroundInstance->_bgRes->_bgInfos[index - 1]._surfInfo._dimensions;
|
|
}
|
|
|
|
void BackgroundInstanceList::refreshPan() {
|
|
BackgroundInstance *backgroundInstance = findActiveBackgroundInstance();
|
|
if (backgroundInstance) {
|
|
WidthHeight dimensions = getMasterBgDimensions();
|
|
_vm->_camera->refreshPan(backgroundInstance, dimensions);
|
|
}
|
|
}
|
|
|
|
bool BackgroundInstanceList::findActiveBackgroundNamedPoint(uint32 namedPointId, Common::Point &pt) {
|
|
BackgroundResource *backgroundResource = getActiveBgResource();
|
|
return backgroundResource ? backgroundResource->findNamedPoint(namedPointId, pt) : false;
|
|
}
|
|
|
|
} // End of namespace Illusions
|