Initial commit
This commit is contained in:
312
engines/illusions/resources/actorresource.cpp
Normal file
312
engines/illusions/resources/actorresource.cpp
Normal file
@@ -0,0 +1,312 @@
|
||||
/* 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 "illusions/actor.h"
|
||||
#include "illusions/illusions.h"
|
||||
#include "illusions/resources/actorresource.h"
|
||||
#include "illusions/dictionary.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
// ActorResourceLoader
|
||||
|
||||
void ActorResourceLoader::load(Resource *resource) {
|
||||
resource->_instance = _vm->_actorInstances->createActorInstance(resource);
|
||||
}
|
||||
|
||||
bool ActorResourceLoader::isFlag(int flag) {
|
||||
return
|
||||
flag == kRlfLoadFile;
|
||||
}
|
||||
|
||||
// Frame
|
||||
|
||||
void Frame::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
||||
_flags = stream.readUint16LE();
|
||||
stream.skip(2); // Skip padding
|
||||
uint32 pointsConfigOffs = stream.readUint32LE();
|
||||
_surfInfo.load(stream);
|
||||
uint32 compressedPixelsOffs = stream.readUint32LE();
|
||||
_compressedPixels = dataStart + compressedPixelsOffs;
|
||||
_pointsConfig = dataStart + pointsConfigOffs;
|
||||
debug(5, "Frame::load() compressedPixelsOffs: %08X",
|
||||
compressedPixelsOffs);
|
||||
}
|
||||
|
||||
// Sequence
|
||||
|
||||
void Sequence::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
||||
_sequenceId = stream.readUint32LE();
|
||||
_unk4 = stream.readUint32LE();
|
||||
uint32 sequenceCodeOffs = stream.readUint32LE();
|
||||
_sequenceCode = dataStart + sequenceCodeOffs;
|
||||
debug(5, "Sequence::load() _sequenceId: %08X; _unk4: %d; sequenceCodeOffs: %08X",
|
||||
_sequenceId, _unk4, sequenceCodeOffs);
|
||||
}
|
||||
|
||||
// ActorType
|
||||
|
||||
void ActorType::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
||||
_actorTypeId = stream.readUint32LE();
|
||||
_surfInfo.load(stream);
|
||||
uint32 pointsConfigOffs = stream.readUint32LE();
|
||||
uint namedPointsCount = stream.readUint16LE();
|
||||
stream.skip(2); // Skip padding
|
||||
uint32 namedPointsOffs = stream.readUint32LE();
|
||||
_color.r = stream.readByte();
|
||||
_color.g = stream.readByte();
|
||||
_color.b = stream.readByte();
|
||||
stream.readByte(); // Skip padding
|
||||
_scale = stream.readByte();
|
||||
_priority = stream.readByte();
|
||||
_value1E = stream.readUint16LE();
|
||||
_pathWalkPointsIndex = stream.readUint16LE();
|
||||
_scaleLayerIndex = stream.readUint16LE();
|
||||
_pathWalkRectIndex = stream.readUint16LE();
|
||||
_priorityLayerIndex = stream.readUint16LE();
|
||||
_regionLayerIndex = stream.readUint16LE();
|
||||
_flags = stream.readUint16LE();
|
||||
_pointsConfig = dataStart + pointsConfigOffs;
|
||||
stream.seek(namedPointsOffs);
|
||||
_namedPoints.load(namedPointsCount, stream);
|
||||
debug(5, "ActorType::load() _actorTypeId: %08X; _color(%d,%d,%d); _scale: %d; _priority: %d; _value1E: %d",
|
||||
_actorTypeId, _color.r, _color.g, _color.b, _scale, _priority, _value1E);
|
||||
debug(5, "ActorType::load() _pathWalkPointsIndex: %d; _scaleLayerIndex: %d; _pathWalkRectIndex: %d",
|
||||
_pathWalkPointsIndex, _scaleLayerIndex, _pathWalkRectIndex);
|
||||
debug(5, "ActorType::load() _priorityLayerIndex: %d; _regionLayerIndex: %d; _flags: %04X",
|
||||
_priorityLayerIndex, _regionLayerIndex,_flags);
|
||||
}
|
||||
|
||||
// ActorResource
|
||||
|
||||
ActorResource::ActorResource() {
|
||||
}
|
||||
|
||||
ActorResource::~ActorResource() {
|
||||
}
|
||||
|
||||
void ActorResource::load(Resource *resource) {
|
||||
byte *data = resource->_data;
|
||||
uint32 dataSize = resource->_dataSize;
|
||||
Common::MemoryReadStream stream(data, dataSize, DisposeAfterUse::NO);
|
||||
|
||||
_totalSize = stream.readUint32LE();
|
||||
|
||||
// Load actor types
|
||||
stream.seek(0x06);
|
||||
uint actorTypesCount = stream.readUint16LE();
|
||||
stream.seek(0x10);
|
||||
uint32 actorTypesOffs = stream.readUint32LE();
|
||||
_actorTypes.reserve(actorTypesCount);
|
||||
for (uint i = 0; i < actorTypesCount; ++i) {
|
||||
ActorType actorType;
|
||||
stream.seek(actorTypesOffs + i * 0x2C);
|
||||
actorType.load(data, stream);
|
||||
_actorTypes.push_back(actorType);
|
||||
}
|
||||
|
||||
// Load sequences
|
||||
stream.seek(0x08);
|
||||
uint sequencesCount = stream.readUint16LE();
|
||||
stream.seek(0x14);
|
||||
uint32 sequencesOffs = stream.readUint32LE();
|
||||
stream.seek(sequencesOffs);
|
||||
_sequences.reserve(sequencesCount);
|
||||
for (uint i = 0; i < sequencesCount; ++i) {
|
||||
Sequence sequence;
|
||||
sequence.load(data, stream);
|
||||
_sequences.push_back(sequence);
|
||||
}
|
||||
|
||||
// Load frames
|
||||
stream.seek(0x0A);
|
||||
uint framesCount = stream.readUint16LE();
|
||||
stream.seek(0x18);
|
||||
uint32 framesOffs = stream.readUint32LE();
|
||||
stream.seek(framesOffs);
|
||||
_frames.reserve(framesCount);
|
||||
for (uint i = 0; i < framesCount; ++i) {
|
||||
Frame frame;
|
||||
frame.load(data, stream);
|
||||
_frames.push_back(frame);
|
||||
}
|
||||
|
||||
// Load named points
|
||||
if (resource->_gameId == kGameIdBBDOU) {
|
||||
// The count isn't stored explicitly so calculate it
|
||||
uint namedPointsCount = (actorTypesOffs - 0x20) / 8;
|
||||
stream.seek(0x20);
|
||||
_namedPoints.load(namedPointsCount, stream);
|
||||
}
|
||||
|
||||
debug(1, "ActorResource(%08X) framesCount: %d", resource->_resId, framesCount);
|
||||
}
|
||||
|
||||
bool ActorResource::containsSequence(Sequence *sequence) {
|
||||
for (uint i = 0; i < _sequences.size(); ++i) {
|
||||
if (sequence == &_sequences[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ActorResource::findNamedPoint(uint32 namedPointId, Common::Point &pt) {
|
||||
return _namedPoints.findNamedPoint(namedPointId, pt);
|
||||
}
|
||||
|
||||
// ActorInstance
|
||||
|
||||
ActorInstance::ActorInstance(IllusionsEngine *vm)
|
||||
: _vm(vm) {
|
||||
}
|
||||
|
||||
void ActorInstance::load(Resource *resource) {
|
||||
_actorResource = new ActorResource();
|
||||
_actorResource->load(resource);
|
||||
_sceneId = resource->_sceneId;
|
||||
_pauseCtr = 0;
|
||||
initActorTypes(resource->_gameId);
|
||||
}
|
||||
|
||||
void ActorInstance::unload() {
|
||||
if (_pauseCtr <= 0)
|
||||
unregisterResources();
|
||||
_vm->_actorInstances->removeActorInstance(this);
|
||||
delete _actorResource;
|
||||
}
|
||||
|
||||
void ActorInstance::pause() {
|
||||
++_pauseCtr;
|
||||
if (_pauseCtr == 1)
|
||||
unregisterResources();
|
||||
}
|
||||
|
||||
void ActorInstance::unpause() {
|
||||
--_pauseCtr;
|
||||
if (_pauseCtr == 0)
|
||||
registerResources();
|
||||
}
|
||||
|
||||
void ActorInstance::initActorTypes(int gameId) {
|
||||
for (uint i = 0; i < _actorResource->_actorTypes.size(); ++i) {
|
||||
ActorType *actorType = &_actorResource->_actorTypes[i];
|
||||
ActorType *actorType2 = _vm->_dict->findActorType(actorType->_actorTypeId);
|
||||
if (actorType2) {
|
||||
actorType->_surfInfo._dimensions._width = MAX(actorType->_surfInfo._dimensions._width,
|
||||
actorType2->_surfInfo._dimensions._width);
|
||||
actorType->_surfInfo._dimensions._height = MAX(actorType->_surfInfo._dimensions._height,
|
||||
actorType2->_surfInfo._dimensions._height);
|
||||
if (actorType->_color.r == 255 && actorType->_color.g == 255 && actorType->_color.b == 255)
|
||||
actorType->_color = actorType2->_color;
|
||||
if (actorType->_value1E == 0)
|
||||
actorType->_value1E = actorType2->_value1E;
|
||||
}
|
||||
_vm->_dict->addActorType(actorType->_actorTypeId, actorType);
|
||||
}
|
||||
for (uint i = 0; i < _actorResource->_sequences.size(); ++i) {
|
||||
Sequence *sequence = &_actorResource->_sequences[i];
|
||||
_vm->_dict->addSequence(sequence->_sequenceId, sequence);
|
||||
if (gameId == kGameIdDuckman && sequence->_sequenceId == 0x60101) {
|
||||
// TODO check that this is the correct location for this logic.
|
||||
_vm->_controls->placeActor(0x50023, Common::Point(0,0), sequence->_sequenceId, 0x400d7, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActorInstance::registerResources() {
|
||||
for (uint i = 0; i < _actorResource->_actorTypes.size(); ++i) {
|
||||
ActorType *actorType = &_actorResource->_actorTypes[i];
|
||||
_vm->_dict->addActorType(actorType->_actorTypeId, actorType);
|
||||
}
|
||||
for (uint i = 0; i < _actorResource->_sequences.size(); ++i) {
|
||||
Sequence *sequence = &_actorResource->_sequences[i];
|
||||
_vm->_dict->addSequence(sequence->_sequenceId, sequence);
|
||||
}
|
||||
}
|
||||
|
||||
void ActorInstance::unregisterResources() {
|
||||
for (uint i = 0; i < _actorResource->_actorTypes.size(); ++i) {
|
||||
_vm->_dict->removeActorType(_actorResource->_actorTypes[i]._actorTypeId);
|
||||
}
|
||||
for (uint i = 0; i < _actorResource->_sequences.size(); ++i) {
|
||||
_vm->_dict->removeSequence(_actorResource->_sequences[i]._sequenceId);
|
||||
}
|
||||
}
|
||||
|
||||
// ActorInstanceList
|
||||
|
||||
ActorInstanceList::ActorInstanceList(IllusionsEngine *vm)
|
||||
: _vm(vm) {
|
||||
}
|
||||
|
||||
ActorInstanceList::~ActorInstanceList() {
|
||||
}
|
||||
|
||||
ActorInstance *ActorInstanceList::createActorInstance(Resource *resource) {
|
||||
ActorInstance *actorInstance = new ActorInstance(_vm);
|
||||
actorInstance->load(resource);
|
||||
_items.push_back(actorInstance);
|
||||
return actorInstance;
|
||||
}
|
||||
|
||||
void ActorInstanceList::removeActorInstance(ActorInstance *actorInstance) {
|
||||
_items.remove(actorInstance);
|
||||
}
|
||||
|
||||
void ActorInstanceList::pauseBySceneId(uint32 sceneId) {
|
||||
for (auto &it : _items) {
|
||||
if (it->_sceneId == sceneId)
|
||||
it->pause();
|
||||
}
|
||||
}
|
||||
|
||||
void ActorInstanceList::unpauseBySceneId(uint32 sceneId) {
|
||||
for (auto &it : _items) {
|
||||
if (it->_sceneId == sceneId)
|
||||
it->unpause();
|
||||
}
|
||||
}
|
||||
|
||||
FramesList *ActorInstanceList::findSequenceFrames(Sequence *sequence) {
|
||||
for (auto &actorInstance : _items) {
|
||||
if (actorInstance->_pauseCtr <= 0 && actorInstance->_actorResource->containsSequence(sequence))
|
||||
return &actorInstance->_actorResource->_frames;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ActorInstance *ActorInstanceList::findActorByResource(ActorResource *actorResource) {
|
||||
for (auto &it : _items) {
|
||||
if (it->_actorResource == actorResource)
|
||||
return (it);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ActorInstanceList::findNamedPoint(uint32 namedPointId, Common::Point &pt) {
|
||||
for (auto &actorInstance : _items) {
|
||||
if (actorInstance->_pauseCtr == 0 && actorInstance->_actorResource->findNamedPoint(namedPointId, pt))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace Illusions
|
||||
132
engines/illusions/resources/actorresource.h
Normal file
132
engines/illusions/resources/actorresource.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ILLUSIONS_ACTORRESOURCE_H
|
||||
#define ILLUSIONS_ACTORRESOURCE_H
|
||||
|
||||
#include "illusions/graphics.h"
|
||||
#include "illusions/resourcesystem.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
class IllusionsEngine;
|
||||
|
||||
class ActorResourceLoader : public BaseResourceLoader {
|
||||
public:
|
||||
ActorResourceLoader(IllusionsEngine *vm) : _vm(vm) {}
|
||||
~ActorResourceLoader() override {}
|
||||
void load(Resource *resource) override;
|
||||
bool isFlag(int flag) override;
|
||||
protected:
|
||||
IllusionsEngine *_vm;
|
||||
};
|
||||
|
||||
struct Frame {
|
||||
uint16 _flags;
|
||||
byte *_pointsConfig;
|
||||
SurfInfo _surfInfo;
|
||||
byte *_compressedPixels;
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
struct Sequence {
|
||||
uint32 _sequenceId;
|
||||
uint32 _unk4;
|
||||
byte *_sequenceCode;
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
struct ActorType {
|
||||
uint32 _actorTypeId;
|
||||
SurfInfo _surfInfo;
|
||||
byte *_pointsConfig;
|
||||
NamedPoints _namedPoints;
|
||||
RGB _color;
|
||||
byte _scale;
|
||||
byte _priority;
|
||||
int16 _value1E;
|
||||
uint16 _pathWalkPointsIndex;
|
||||
uint16 _scaleLayerIndex;
|
||||
uint16 _pathWalkRectIndex;
|
||||
uint16 _priorityLayerIndex;
|
||||
uint16 _regionLayerIndex;
|
||||
uint16 _flags;
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
class FramesList : public Common::Array<Frame> {
|
||||
};
|
||||
|
||||
class ActorResource {
|
||||
public:
|
||||
ActorResource();
|
||||
~ActorResource();
|
||||
void load(Resource *resource);
|
||||
bool containsSequence(Sequence *sequence);
|
||||
bool findNamedPoint(uint32 namedPointId, Common::Point &pt);
|
||||
public:
|
||||
uint32 _totalSize;
|
||||
Common::Array<ActorType> _actorTypes;
|
||||
Common::Array<Sequence> _sequences;
|
||||
FramesList _frames;
|
||||
NamedPoints _namedPoints;
|
||||
};
|
||||
|
||||
class ActorInstance : public ResourceInstance {
|
||||
public:
|
||||
ActorInstance(IllusionsEngine *vm);
|
||||
void load(Resource *resource) override;
|
||||
void unload() override;
|
||||
void pause() override;
|
||||
void unpause() override;
|
||||
public:
|
||||
IllusionsEngine *_vm;
|
||||
uint32 _sceneId;
|
||||
int _pauseCtr;
|
||||
ActorResource *_actorResource;
|
||||
protected:
|
||||
void initActorTypes(int gameId);
|
||||
void registerResources();
|
||||
void unregisterResources();
|
||||
};
|
||||
|
||||
class ActorInstanceList {
|
||||
public:
|
||||
ActorInstanceList(IllusionsEngine *vm);
|
||||
~ActorInstanceList();
|
||||
ActorInstance *createActorInstance(Resource *resource);
|
||||
void removeActorInstance(ActorInstance *actorInstance);
|
||||
void pauseBySceneId(uint32 sceneId);
|
||||
void unpauseBySceneId(uint32 sceneId);
|
||||
FramesList *findSequenceFrames(Sequence *sequence);
|
||||
ActorInstance *findActorByResource(ActorResource *actorResource);
|
||||
bool findNamedPoint(uint32 namedPointId, Common::Point &pt);
|
||||
protected:
|
||||
typedef Common::List<ActorInstance*> Items;
|
||||
typedef Items::iterator ItemsIterator;
|
||||
IllusionsEngine *_vm;
|
||||
Items _items;
|
||||
};
|
||||
|
||||
} // End of namespace Illusions
|
||||
|
||||
#endif // ILLUSIONS_ACTORRESOURCE_H
|
||||
641
engines/illusions/resources/backgroundresource.cpp
Normal file
641
engines/illusions/resources/backgroundresource.cpp
Normal file
@@ -0,0 +1,641 @@
|
||||
/* 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 "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(nullptr), _scaleLayers(nullptr), _priorityLayers(nullptr), _regionLayers(nullptr),
|
||||
_regionSequences(nullptr), _backgroundObjects(nullptr), _pathWalkPoints(nullptr),
|
||||
_pathWalkRects(nullptr), _palettes(nullptr) {
|
||||
}
|
||||
|
||||
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(nullptr), _savedPalette(nullptr) {
|
||||
}
|
||||
|
||||
BackgroundInstance::~BackgroundInstance() {
|
||||
delete[] _savedPalette;
|
||||
}
|
||||
|
||||
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 = nullptr;
|
||||
_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] = nullptr;
|
||||
}
|
||||
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] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 (auto &item : _items) {
|
||||
if (item->_sceneId == sceneId)
|
||||
item->pause();
|
||||
}
|
||||
}
|
||||
|
||||
void BackgroundInstanceList::unpauseBySceneId(uint32 sceneId) {
|
||||
for (auto &item : _items) {
|
||||
if (item->_sceneId == sceneId)
|
||||
item->unpause();
|
||||
}
|
||||
}
|
||||
|
||||
BackgroundInstance *BackgroundInstanceList::findActiveBackgroundInstance() {
|
||||
for (auto &item : _items) {
|
||||
if (item->_pauseCtr == 0)
|
||||
return item;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BackgroundInstance *BackgroundInstanceList::findBackgroundByResource(BackgroundResource *backgroundResource) {
|
||||
for (auto &item : _items) {
|
||||
if (item->_bgRes == backgroundResource)
|
||||
return item;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BackgroundResource *BackgroundInstanceList::getActiveBgResource() {
|
||||
BackgroundInstance *background = findActiveBackgroundInstance();
|
||||
if (background)
|
||||
return background->_bgRes;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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
|
||||
233
engines/illusions/resources/backgroundresource.h
Normal file
233
engines/illusions/resources/backgroundresource.h
Normal file
@@ -0,0 +1,233 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ILLUSIONS_BACKGROUNDRESOURCE_H
|
||||
#define ILLUSIONS_BACKGROUNDRESOURCE_H
|
||||
|
||||
#include "illusions/camera.h"
|
||||
#include "illusions/graphics.h"
|
||||
#include "illusions/pathfinder.h"
|
||||
#include "illusions/resourcesystem.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/file.h"
|
||||
#include "common/list.h"
|
||||
#include "common/memstream.h"
|
||||
#include "common/rect.h"
|
||||
#include "common/substream.h"
|
||||
#include "common/system.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
class IllusionsEngine;
|
||||
struct Sequence;
|
||||
|
||||
class BackgroundResourceLoader : public BaseResourceLoader {
|
||||
public:
|
||||
BackgroundResourceLoader(IllusionsEngine *vm) : _vm(vm) {}
|
||||
~BackgroundResourceLoader() override {}
|
||||
void load(Resource *resource) override;
|
||||
bool isFlag(int flag) override;
|
||||
protected:
|
||||
IllusionsEngine *_vm;
|
||||
};
|
||||
|
||||
struct TileMap {
|
||||
int16 _width, _height;
|
||||
//field_4 dd
|
||||
byte *_map;
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
struct BgInfo {
|
||||
uint32 _flags;
|
||||
//field_4 dw
|
||||
int16 _priorityBase;
|
||||
SurfInfo _surfInfo;
|
||||
Common::Point _panPoint;
|
||||
TileMap _tileMap;
|
||||
byte *_tilePixels;
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
class PriorityLayer {
|
||||
public:
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
int getPriority(Common::Point pos);
|
||||
protected:
|
||||
int16 _width, _height;
|
||||
int16 _mapWidth, _mapHeight;
|
||||
byte *_map, *_values;
|
||||
};
|
||||
|
||||
class ScaleLayer {
|
||||
public:
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
int getScale(Common::Point pos);
|
||||
protected:
|
||||
int16 _height;
|
||||
byte *_values;
|
||||
};
|
||||
|
||||
class RegionLayer {
|
||||
public:
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
int getRegionIndex(Common::Point pos);
|
||||
uint32 getRegionSequenceId(int regionIndex);
|
||||
protected:
|
||||
uint32 _unk;
|
||||
byte *_regionSequenceIds;
|
||||
int16 _width, _height;
|
||||
int16 _mapWidth, _mapHeight;
|
||||
byte *_map, *_values;
|
||||
};
|
||||
|
||||
struct Palette {
|
||||
uint16 _count;
|
||||
uint16 _unk;
|
||||
byte *_palette;
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
struct BackgroundObject {
|
||||
uint32 _objectId;
|
||||
uint16 _flags;
|
||||
int16 _priority;
|
||||
byte *_pointsConfig;
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
struct PathWalkPoints {
|
||||
PointArray *_points;
|
||||
PathWalkPoints() : _points(0) {}
|
||||
~PathWalkPoints() { delete _points; }
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
struct PathWalkRects {
|
||||
PathLines *_rects;
|
||||
PathWalkRects() : _rects(0) {}
|
||||
~PathWalkRects() { delete _rects; }
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
class BackgroundResource {
|
||||
public:
|
||||
BackgroundResource();
|
||||
~BackgroundResource();
|
||||
void load(byte *data, uint32 dataSize);
|
||||
int findMasterBgIndex();
|
||||
PriorityLayer *getPriorityLayer(uint index);
|
||||
ScaleLayer *getScaleLayer(uint index);
|
||||
RegionLayer *getRegionLayer(uint index);
|
||||
PathWalkPoints *getPathWalkPoints(uint index);
|
||||
PathWalkRects *getPathWalkRects(uint index);
|
||||
Palette *getPalette(uint index);
|
||||
bool findNamedPoint(uint32 namedPointId, Common::Point &pt);
|
||||
public:
|
||||
|
||||
uint _paletteIndex;
|
||||
|
||||
uint _bgInfosCount;
|
||||
BgInfo *_bgInfos;
|
||||
|
||||
uint _priorityLayersCount;
|
||||
PriorityLayer *_priorityLayers;
|
||||
|
||||
uint _scaleLayersCount;
|
||||
ScaleLayer *_scaleLayers;
|
||||
|
||||
uint _regionLayersCount;
|
||||
RegionLayer *_regionLayers;
|
||||
|
||||
uint _regionSequencesCount;
|
||||
Sequence *_regionSequences;
|
||||
|
||||
uint _backgroundObjectsCount;
|
||||
BackgroundObject *_backgroundObjects;
|
||||
|
||||
uint _pathWalkPointsCount;
|
||||
PathWalkPoints *_pathWalkPoints;
|
||||
|
||||
uint _pathWalkRectsCount;
|
||||
PathWalkRects *_pathWalkRects;
|
||||
|
||||
NamedPoints _namedPoints;
|
||||
|
||||
uint _palettesCount;
|
||||
Palette *_palettes;
|
||||
|
||||
};
|
||||
|
||||
const uint kMaxBackgroundItemSurfaces = 3;
|
||||
|
||||
class BackgroundInstance : public ResourceInstance {
|
||||
public:
|
||||
BackgroundInstance(IllusionsEngine *vm);
|
||||
~BackgroundInstance();
|
||||
void load(Resource *resource) override;
|
||||
void unload() override;
|
||||
void pause() override;
|
||||
void unpause() override;
|
||||
public:
|
||||
IllusionsEngine *_vm;
|
||||
uint32 _sceneId;
|
||||
int _pauseCtr;
|
||||
BackgroundResource *_bgRes;
|
||||
Common::Point _panPoints[kMaxBackgroundItemSurfaces];
|
||||
Graphics::Surface *_surfaces[kMaxBackgroundItemSurfaces];
|
||||
CameraState _savedCameraState;
|
||||
byte *_savedPalette;
|
||||
void registerResources();
|
||||
void unregisterResources();
|
||||
void initSurface();
|
||||
void freeSurface();
|
||||
void drawTiles(Graphics::Surface *surface, TileMap &tileMap, byte *tilePixels);
|
||||
void drawTiles8(Graphics::Surface *surface, TileMap &tileMap, byte *tilePixels);
|
||||
void drawTiles16(Graphics::Surface *surface, TileMap &tileMap, byte *tilePixels);
|
||||
};
|
||||
|
||||
class BackgroundInstanceList {
|
||||
public:
|
||||
BackgroundInstanceList(IllusionsEngine *vm);
|
||||
~BackgroundInstanceList();
|
||||
BackgroundInstance *createBackgroundInstance(Resource *resource);
|
||||
void removeBackgroundInstance(BackgroundInstance *backgroundInstance);
|
||||
void pauseBySceneId(uint32 sceneId);
|
||||
void unpauseBySceneId(uint32 sceneId);
|
||||
BackgroundInstance *findActiveBackgroundInstance();
|
||||
BackgroundInstance *findBackgroundByResource(BackgroundResource *backgroundResource);
|
||||
BackgroundResource *getActiveBgResource();
|
||||
WidthHeight getMasterBgDimensions();
|
||||
void refreshPan();
|
||||
bool findActiveBackgroundNamedPoint(uint32 namedPointId, Common::Point &pt);
|
||||
//protected:
|
||||
public:
|
||||
typedef Common::List<BackgroundInstance*> Items;
|
||||
typedef Items::iterator ItemsIterator;
|
||||
IllusionsEngine *_vm;
|
||||
Items _items;
|
||||
};
|
||||
|
||||
} // End of namespace Illusions
|
||||
|
||||
#endif // ILLUSIONS_BACKGROUNDRESOURCE_H
|
||||
147
engines/illusions/resources/fontresource.cpp
Normal file
147
engines/illusions/resources/fontresource.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
/* 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 "illusions/illusions.h"
|
||||
#include "illusions/resources/fontresource.h"
|
||||
#include "illusions/dictionary.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
// FontResourceLoader
|
||||
|
||||
void FontResourceLoader::load(Resource *resource) {
|
||||
FontInstance *fontInstance = new FontInstance(_vm);
|
||||
fontInstance->load(resource);
|
||||
resource->_instance = fontInstance;
|
||||
}
|
||||
|
||||
bool FontResourceLoader::isFlag(int flag) {
|
||||
return
|
||||
flag == kRlfLoadFile;
|
||||
}
|
||||
|
||||
// CharInfo
|
||||
|
||||
void CharInfo::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
||||
_width = stream.readUint16LE();
|
||||
_field_2 = stream.readUint16LE();
|
||||
uint32 pixelsOffs = stream.readUint32LE();
|
||||
_pixels = dataStart + pixelsOffs;
|
||||
debug(2, "CharInfo::load() _width: %d; _field_2: %d; pixelsOffs: %08X",
|
||||
_width, _field_2, pixelsOffs);
|
||||
}
|
||||
|
||||
// CharRange
|
||||
|
||||
CharRange::CharRange() : _charInfos(nullptr) {
|
||||
}
|
||||
|
||||
CharRange::~CharRange() {
|
||||
delete[] _charInfos;
|
||||
}
|
||||
|
||||
void CharRange::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
||||
_firstChar = stream.readUint16LE();
|
||||
_lastChar = stream.readUint16LE();
|
||||
uint count = _lastChar - _firstChar + 1;
|
||||
uint32 charInfosOffs = stream.readUint32LE();
|
||||
_charInfos = new CharInfo[count];
|
||||
for (uint i = 0; i < count; ++i) {
|
||||
stream.seek(charInfosOffs + i * 8);
|
||||
_charInfos[i].load(dataStart, stream);
|
||||
}
|
||||
debug(2, "CharRange::load() _firstChar: %d; _lastChar: %d; charInfosOffs: %08X",
|
||||
_firstChar, _lastChar, charInfosOffs);
|
||||
}
|
||||
|
||||
CharInfo *CharRange::getCharInfo(uint16 c) {
|
||||
return &_charInfos[c - _firstChar];
|
||||
}
|
||||
|
||||
bool CharRange::containsChar(uint16 c) {
|
||||
return c >= _firstChar && c <= _lastChar;
|
||||
}
|
||||
|
||||
// FontResource
|
||||
|
||||
FontResource::FontResource() : _charRanges(nullptr) {
|
||||
}
|
||||
|
||||
FontResource::~FontResource() {
|
||||
delete[] _charRanges;
|
||||
}
|
||||
|
||||
void FontResource::load(Resource *resource) {
|
||||
byte *data = resource->_data;
|
||||
uint32 dataSize = resource->_dataSize;
|
||||
Common::MemoryReadStream stream(data, dataSize, DisposeAfterUse::NO);
|
||||
_totalSize = stream.readUint32LE();
|
||||
_charHeight = stream.readUint16LE();
|
||||
_defaultChar = stream.readUint16LE();
|
||||
_colorIndex = stream.readUint16LE();
|
||||
_lineIncr = stream.readUint16LE();
|
||||
_widthC = stream.readUint16LE();
|
||||
_charRangesCount = stream.readUint16LE();
|
||||
uint32 charRangesOffs = stream.pos();
|
||||
_charRanges = new CharRange[_charRangesCount];
|
||||
for (uint i = 0; i < _charRangesCount; ++i) {
|
||||
stream.seek(charRangesOffs + i * 8);
|
||||
_charRanges[i].load(data, stream);
|
||||
}
|
||||
debug(2, "FontResource::load() _charHeight: %d; _defaultChar: %d; _colorIndex: %d; _lineIncr: %d; _widthC: %d; _charRangesCount: %d",
|
||||
_charHeight, _defaultChar, _colorIndex, _lineIncr, _widthC, _charRangesCount);
|
||||
}
|
||||
|
||||
CharInfo *FontResource::getCharInfo(uint16 c) {
|
||||
for (uint i = 0; i < _charRangesCount; ++i) {
|
||||
if (_charRanges[i].containsChar(c))
|
||||
return _charRanges[i].getCharInfo(c);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Common::Rect FontResource::calculateRectForText(uint16 *text, uint textLength) {
|
||||
int16 width = 0;
|
||||
for (uint i = 0; i < textLength && *text; i++) {
|
||||
width += getCharInfo(*text)->_width;
|
||||
text++;
|
||||
}
|
||||
return Common::Rect(width, getCharHeight() + getLineIncr());
|
||||
}
|
||||
|
||||
// FontInstance
|
||||
|
||||
FontInstance::FontInstance(IllusionsEngine *vm) : _vm(vm) {
|
||||
}
|
||||
|
||||
void FontInstance::load(Resource *resource) {
|
||||
_fontResource = new FontResource();
|
||||
_fontResource->load(resource);
|
||||
_resId = resource->_resId;
|
||||
_vm->_dict->addFont(resource->_resId, _fontResource);
|
||||
}
|
||||
|
||||
void FontInstance::unload() {
|
||||
delete _fontResource;
|
||||
_vm->_dict->removeFont(_resId);
|
||||
}
|
||||
|
||||
} // End of namespace Illusions
|
||||
95
engines/illusions/resources/fontresource.h
Normal file
95
engines/illusions/resources/fontresource.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ILLUSIONS_FONTRESOURCE_H
|
||||
#define ILLUSIONS_FONTRESOURCE_H
|
||||
|
||||
#include "illusions/graphics.h"
|
||||
#include "illusions/resourcesystem.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
class IllusionsEngine;
|
||||
|
||||
class FontResourceLoader : public BaseResourceLoader {
|
||||
public:
|
||||
FontResourceLoader(IllusionsEngine *vm) : _vm(vm) {}
|
||||
~FontResourceLoader() override {}
|
||||
void load(Resource *resource) override;
|
||||
bool isFlag(int flag) override;
|
||||
protected:
|
||||
IllusionsEngine *_vm;
|
||||
};
|
||||
|
||||
struct CharInfo {
|
||||
int16 _width;
|
||||
int16 _field_2;
|
||||
byte *_pixels;
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
struct CharRange {
|
||||
CharRange();
|
||||
~CharRange();
|
||||
uint16 _firstChar;
|
||||
uint16 _lastChar;
|
||||
CharInfo *_charInfos;
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
CharInfo *getCharInfo(uint16 c);
|
||||
bool containsChar(uint16 c);
|
||||
};
|
||||
|
||||
class FontResource {
|
||||
public:
|
||||
FontResource();
|
||||
~FontResource();
|
||||
void load(Resource *resource);
|
||||
CharInfo *getCharInfo(uint16 c);
|
||||
int16 getColorIndex() const { return _colorIndex; }
|
||||
int16 getCharHeight() const { return _charHeight; }
|
||||
int16 getLineIncr() const { return _lineIncr; }
|
||||
const Common::Rect calculateRectForText(uint16 *text, uint textLength);
|
||||
public:
|
||||
uint32 _totalSize;
|
||||
int16 _charHeight;
|
||||
int16 _defaultChar;
|
||||
int16 _colorIndex;
|
||||
int16 _lineIncr;
|
||||
int16 _widthC;
|
||||
uint _charRangesCount;
|
||||
CharRange *_charRanges;
|
||||
CharRange *getCharRange(uint16 c);
|
||||
};
|
||||
|
||||
class FontInstance : public ResourceInstance {
|
||||
public:
|
||||
FontInstance(IllusionsEngine *vm);
|
||||
void load(Resource *resource) override;
|
||||
void unload() override;
|
||||
public:
|
||||
IllusionsEngine *_vm;
|
||||
FontResource *_fontResource;
|
||||
uint32 _resId;
|
||||
};
|
||||
|
||||
} // End of namespace Illusions
|
||||
|
||||
#endif // ILLUSIONS_FONTRESOURCE_H
|
||||
39
engines/illusions/resources/genericresource.cpp
Normal file
39
engines/illusions/resources/genericresource.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/* 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 "illusions/illusions.h"
|
||||
#include "illusions/resources/genericresource.h"
|
||||
#include "illusions/dictionary.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
// GenericResourceLoader
|
||||
|
||||
void GenericResourceLoader::load(Resource *resource) {
|
||||
resource->_instance = nullptr;
|
||||
}
|
||||
|
||||
bool GenericResourceLoader::isFlag(int flag) {
|
||||
return
|
||||
flag == kRlfLoadFile;
|
||||
}
|
||||
|
||||
} // End of namespace Illusions
|
||||
44
engines/illusions/resources/genericresource.h
Normal file
44
engines/illusions/resources/genericresource.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ILLUSIONS_GENERICRESOURCE_H
|
||||
#define ILLUSIONS_GENERICRESOURCE_H
|
||||
|
||||
#include "illusions/graphics.h"
|
||||
#include "illusions/resourcesystem.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
class IllusionsEngine;
|
||||
|
||||
class GenericResourceLoader : public BaseResourceLoader {
|
||||
public:
|
||||
GenericResourceLoader(IllusionsEngine *vm) : _vm(vm) {}
|
||||
~GenericResourceLoader() override {}
|
||||
void load(Resource *resource) override;
|
||||
bool isFlag(int flag) override;
|
||||
protected:
|
||||
IllusionsEngine *_vm;
|
||||
};
|
||||
|
||||
} // End of namespace Illusions
|
||||
|
||||
#endif // ILLUSIONS_GENERICRESOURCE_H
|
||||
99
engines/illusions/resources/midiresource.cpp
Normal file
99
engines/illusions/resources/midiresource.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/* 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 "illusions/illusions.h"
|
||||
#include "illusions/resources/midiresource.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
// MidiGroupResourceLoader
|
||||
|
||||
void MidiGroupResourceLoader::load(Resource *resource) {
|
||||
debug(1, "MidiGroupResourceLoader::load() Loading midi group %08X...", resource->_resId);
|
||||
MidiGroupInstance *midiGroupInstance = new MidiGroupInstance(_vm);
|
||||
midiGroupInstance->load(resource);
|
||||
resource->_instance = midiGroupInstance;
|
||||
}
|
||||
|
||||
bool MidiGroupResourceLoader::isFlag(int flag) {
|
||||
return
|
||||
flag == kRlfLoadFile/* ||
|
||||
flag == kRlfFreeDataAfterLoad*/;
|
||||
}
|
||||
|
||||
// MidiMusic
|
||||
|
||||
void MidiMusic::load(Common::SeekableReadStream &stream) {
|
||||
_musicId = stream.readUint32LE();
|
||||
_looping = stream.readUint16LE() != 0;
|
||||
stream.skip(2 + 32 + 4); // Skip unused/unknown values
|
||||
debug(1, "MidiMusic::load() _musicId: %08X; _looping: %d", _musicId, _looping);
|
||||
}
|
||||
|
||||
// MidiGroupResource
|
||||
|
||||
MidiGroupResource::MidiGroupResource()
|
||||
: _midiMusicCount(0), _midiMusic(nullptr) {
|
||||
}
|
||||
|
||||
MidiGroupResource::~MidiGroupResource() {
|
||||
delete[] _midiMusic;
|
||||
}
|
||||
|
||||
void MidiGroupResource::load(byte *data, uint32 dataSize) {
|
||||
Common::MemoryReadStream stream(data, dataSize, DisposeAfterUse::NO);
|
||||
|
||||
stream.skip(4);
|
||||
_midiMusicCount = stream.readUint16LE();
|
||||
stream.skip(2);
|
||||
uint32 midiMusicOffs = stream.readUint32LE();
|
||||
debug("_midiMusicCount: %d; midiMusicOffs: %08X", _midiMusicCount, midiMusicOffs);
|
||||
_midiMusic = new MidiMusic[_midiMusicCount];
|
||||
stream.seek(midiMusicOffs);
|
||||
for (uint i = 0; i < _midiMusicCount; ++i) {
|
||||
_midiMusic[i].load(stream);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MidiGroupInstance
|
||||
|
||||
MidiGroupInstance::MidiGroupInstance(IllusionsEngine *vm)
|
||||
: _vm(vm), _midiGroupResource(nullptr) {
|
||||
}
|
||||
|
||||
void MidiGroupInstance::load(Resource *resource) {
|
||||
_midiGroupResource = new MidiGroupResource();
|
||||
_midiGroupResource->load(resource->_data, resource->_dataSize);
|
||||
for (uint i = 0; i < _midiGroupResource->_midiMusicCount; ++i) {
|
||||
// TODO
|
||||
// SoundEffect *soundEffect = &_soundGroupResource->_soundEffects[i];
|
||||
// _vm->_soundMan->loadSound(soundEffect->_soundEffectId, resource->_resId, soundEffect->_looping);
|
||||
}
|
||||
_resId = resource->_resId;
|
||||
}
|
||||
|
||||
void MidiGroupInstance::unload() {
|
||||
// _vm->_soundMan->unloadSounds(_resId);
|
||||
delete _midiGroupResource;
|
||||
}
|
||||
|
||||
} // End of namespace Illusions
|
||||
71
engines/illusions/resources/midiresource.h
Normal file
71
engines/illusions/resources/midiresource.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ILLUSIONS_MIDIRESOURCE_H
|
||||
#define ILLUSIONS_MIDIRESOURCE_H
|
||||
|
||||
#include "illusions/graphics.h"
|
||||
#include "illusions/resourcesystem.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
class IllusionsEngine;
|
||||
|
||||
class MidiGroupResourceLoader : public BaseResourceLoader {
|
||||
public:
|
||||
MidiGroupResourceLoader(IllusionsEngine *vm) : _vm(vm) {}
|
||||
~MidiGroupResourceLoader() override {}
|
||||
void load(Resource *resource) override;
|
||||
bool isFlag(int flag) override;
|
||||
protected:
|
||||
IllusionsEngine *_vm;
|
||||
};
|
||||
|
||||
struct MidiMusic {
|
||||
uint32 _musicId;
|
||||
bool _looping;
|
||||
void load(Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
class MidiGroupResource {
|
||||
public:
|
||||
MidiGroupResource();
|
||||
~MidiGroupResource();
|
||||
void load(byte *data, uint32 dataSize);
|
||||
public:
|
||||
uint _midiMusicCount;
|
||||
MidiMusic *_midiMusic;
|
||||
};
|
||||
|
||||
class MidiGroupInstance : public ResourceInstance {
|
||||
public:
|
||||
MidiGroupInstance(IllusionsEngine *vm);
|
||||
void load(Resource *resource) override;
|
||||
void unload() override;
|
||||
public:
|
||||
IllusionsEngine *_vm;
|
||||
MidiGroupResource *_midiGroupResource;
|
||||
uint32 _resId;
|
||||
};
|
||||
|
||||
} // End of namespace Illusions
|
||||
|
||||
#endif // ILLUSIONS_SOUNDRESOURCE_H
|
||||
413
engines/illusions/resources/scriptresource.cpp
Normal file
413
engines/illusions/resources/scriptresource.cpp
Normal file
@@ -0,0 +1,413 @@
|
||||
/* 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 "illusions/illusions.h"
|
||||
#include "illusions/resources/scriptresource.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
// ScriptResourceLoader
|
||||
|
||||
void ScriptResourceLoader::load(Resource *resource) {
|
||||
ScriptInstance *scriptInstance = new ScriptInstance(_vm);
|
||||
scriptInstance->load(resource);
|
||||
resource->_instance = scriptInstance;
|
||||
}
|
||||
|
||||
bool ScriptResourceLoader::isFlag(int flag) {
|
||||
return
|
||||
flag == kRlfLoadFile;
|
||||
}
|
||||
|
||||
// Properties
|
||||
|
||||
Properties::Properties()
|
||||
: _count(0), _properties(nullptr) {
|
||||
}
|
||||
|
||||
void Properties::init(uint count, byte *properties) {
|
||||
_count = count;
|
||||
_properties = properties;
|
||||
}
|
||||
|
||||
void Properties::clear() {
|
||||
uint32 size = getSize();
|
||||
for (uint32 i = 0; i < size; ++i) {
|
||||
_properties[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool Properties::get(uint32 propertyId) {
|
||||
uint index;
|
||||
byte mask;
|
||||
getProperyPos(propertyId, index, mask);
|
||||
return (_properties[index] & mask) != 0;
|
||||
}
|
||||
|
||||
void Properties::set(uint32 propertyId, bool value) {
|
||||
uint index;
|
||||
byte mask;
|
||||
getProperyPos(propertyId, index, mask);
|
||||
if (value)
|
||||
_properties[index] |= mask;
|
||||
else
|
||||
_properties[index] &= ~mask;
|
||||
}
|
||||
|
||||
uint32 Properties::getSize() {
|
||||
return (_count >> 3) + 1;
|
||||
}
|
||||
|
||||
void Properties::writeToStream(Common::WriteStream *out) {
|
||||
const uint32 size = getSize();
|
||||
out->writeUint32LE(size);
|
||||
out->write(_properties, size);
|
||||
}
|
||||
|
||||
bool Properties::readFromStream(Common::ReadStream *in) {
|
||||
uint32 size = in->readUint32LE();
|
||||
if (size != getSize())
|
||||
return false;
|
||||
in->read(_properties, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Properties::getProperyPos(uint32 propertyId, uint &index, byte &mask) {
|
||||
propertyId &= 0xFFFF;
|
||||
index = propertyId >> 3;
|
||||
mask = 1 << (propertyId & 7);
|
||||
}
|
||||
|
||||
// BlockCounters
|
||||
|
||||
BlockCounters::BlockCounters()
|
||||
: _count(0), _blockCounters(nullptr) {
|
||||
}
|
||||
|
||||
void BlockCounters::init(uint count, byte *blockCounters) {
|
||||
_count = count;
|
||||
_blockCounters = blockCounters;
|
||||
}
|
||||
|
||||
void BlockCounters::clear() {
|
||||
for (uint i = 0; i < _count; ++i) {
|
||||
_blockCounters[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
byte BlockCounters::get(uint index) {
|
||||
return _blockCounters[index - 1] & 0x3F;
|
||||
}
|
||||
|
||||
void BlockCounters::set(uint index, byte value) {
|
||||
_blockCounters[index - 1] ^= (_blockCounters[index - 1] ^ value) & 0x3F;
|
||||
}
|
||||
|
||||
byte BlockCounters::getC0(uint index) {
|
||||
return _blockCounters[index - 1] & 0xC0;
|
||||
}
|
||||
|
||||
void BlockCounters::setC0(uint index, byte value) {
|
||||
byte oldValue = _blockCounters[index - 1] & 0x3F;
|
||||
if (value & 0x80)
|
||||
value = value & 0xBF;
|
||||
_blockCounters[index - 1] = oldValue | (value & 0xC0);
|
||||
}
|
||||
|
||||
uint32 BlockCounters::getSize() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void BlockCounters::writeToStream(Common::WriteStream *out) {
|
||||
const uint32 size = getSize();
|
||||
out->writeUint32LE(size);
|
||||
out->write(_blockCounters, size);
|
||||
}
|
||||
|
||||
bool BlockCounters::readFromStream(Common::ReadStream *in) {
|
||||
uint32 size = in->readUint32LE();
|
||||
if (size != getSize())
|
||||
return false;
|
||||
in->read(_blockCounters, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
// TriggerCause
|
||||
|
||||
void TriggerCause::load(Common::SeekableReadStream &stream) {
|
||||
_verbId = stream.readUint32LE();
|
||||
_objectId2 = stream.readUint32LE();
|
||||
_codeOffs = stream.readUint32LE();
|
||||
|
||||
debug(2, "TriggerCause::load() _verbId: %08X; _objectId2: %08X; _codeOffs: %08X",
|
||||
_verbId, _objectId2, _codeOffs);
|
||||
}
|
||||
|
||||
// TriggerObject
|
||||
|
||||
TriggerObject::TriggerObject()
|
||||
: _causesCount(0), _causes(nullptr) {
|
||||
}
|
||||
|
||||
TriggerObject::~TriggerObject() {
|
||||
delete[] _causes;
|
||||
}
|
||||
|
||||
void TriggerObject::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
||||
_objectId = stream.readUint32LE();
|
||||
_causesCount = stream.readUint16LE();
|
||||
stream.skip(2); // Skip padding
|
||||
debug(2, "TriggerObject::load() _objectId: %08X; _causesCount: %d",
|
||||
_objectId, _causesCount);
|
||||
_causes = new TriggerCause[_causesCount];
|
||||
for (uint i = 0; i < _causesCount; ++i) {
|
||||
_causes[i].load(stream);
|
||||
}
|
||||
}
|
||||
|
||||
bool TriggerObject::findTriggerCause(uint32 verbId, uint32 objectId2, uint32 &codeOffs) {
|
||||
if ((verbId & 0xFFFF0000) == 0) {
|
||||
for (uint i = 0; i < _causesCount; ++i) {
|
||||
if ((verbId == 7 && ((_causes[i]._verbId == 7 && _causes[i]._objectId2 == objectId2) || _causes[i]._verbId == 8)) ||
|
||||
(verbId != 7 && verbId == _causes[i]._verbId)) {
|
||||
codeOffs = _causes[i]._codeOffs;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (uint i = 0; i < _causesCount; ++i) {
|
||||
if (_causes[i]._verbId == verbId && _causes[i]._objectId2 == objectId2) {
|
||||
codeOffs = _causes[i]._codeOffs;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TriggerObject::fixupSceneInfosDuckman() {
|
||||
for (uint i = 0; i < _causesCount; ++i) {
|
||||
_causes[i]._verbId &= 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
// SceneInfo
|
||||
|
||||
SceneInfo::SceneInfo()
|
||||
: _triggerObjectsCount(0), _triggerObjects(nullptr),
|
||||
_resourcesCount(0), _resources(nullptr) {
|
||||
}
|
||||
|
||||
SceneInfo::~SceneInfo() {
|
||||
delete[] _triggerObjects;
|
||||
delete[] _resources;
|
||||
}
|
||||
|
||||
void SceneInfo::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
||||
_id = stream.readUint16LE();
|
||||
_unk = stream.readUint16LE();
|
||||
_name = (uint16 *)(dataStart + stream.pos());
|
||||
swapBytesInWideString((byte *)_name);
|
||||
stream.skip(128);
|
||||
_triggerObjectsCount = stream.readUint16LE();
|
||||
_resourcesCount = stream.readUint16LE();
|
||||
debug(2, "\nSceneInfo::load() _id: %d; _unk: %d; _name: [%s]",
|
||||
_id, _unk, debugW2I(_name));
|
||||
uint32 triggerObjectsListOffs = stream.readUint32LE();
|
||||
if (_resourcesCount > 0) {
|
||||
_resources = new uint32[_resourcesCount];
|
||||
for (uint i = 0; i < _resourcesCount; ++i) {
|
||||
_resources[i] = stream.readUint32LE();
|
||||
}
|
||||
}
|
||||
if (_triggerObjectsCount > 0) {
|
||||
_triggerObjects = new TriggerObject[_triggerObjectsCount];
|
||||
for (uint i = 0; i < _triggerObjectsCount; ++i) {
|
||||
stream.seek(triggerObjectsListOffs + i * 4);
|
||||
uint32 triggerObjectOffs = stream.readUint32LE();
|
||||
stream.seek(triggerObjectOffs);
|
||||
_triggerObjects[i].load(dataStart, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SceneInfo::findTriggerCause(uint32 verbId, uint32 objectId2, uint32 objectId, uint32 &codeOffs) {
|
||||
TriggerObject *triggerObject = findTriggerObject(objectId);
|
||||
if (triggerObject)
|
||||
return triggerObject->findTriggerCause(verbId, objectId2, codeOffs);
|
||||
return false;
|
||||
}
|
||||
|
||||
void SceneInfo::getResources(uint &resourcesCount, uint32 *&resources) {
|
||||
resourcesCount = _resourcesCount;
|
||||
resources = _resources;
|
||||
}
|
||||
|
||||
TriggerObject *SceneInfo::findTriggerObject(uint32 objectId) {
|
||||
for (uint i = 0; i < _triggerObjectsCount; ++i) {
|
||||
if (_triggerObjects[i]._objectId == objectId)
|
||||
return &_triggerObjects[i];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SceneInfo::fixupSceneInfosDuckman() {
|
||||
for (uint i = 0; i < _triggerObjectsCount; ++i) {
|
||||
_triggerObjects[i].fixupSceneInfosDuckman();
|
||||
}
|
||||
}
|
||||
|
||||
// ScriptResource
|
||||
|
||||
ScriptResource::ScriptResource()
|
||||
: _codeOffsets(nullptr), _sceneInfos(nullptr), _objectMap(nullptr) {
|
||||
}
|
||||
|
||||
ScriptResource::~ScriptResource() {
|
||||
delete[] _codeOffsets;
|
||||
delete[] _sceneInfos;
|
||||
delete[] _objectMap;
|
||||
}
|
||||
|
||||
void ScriptResource::load(Resource *resource) {
|
||||
_data = resource->_data;
|
||||
_dataSize = resource->_dataSize;
|
||||
|
||||
Common::MemoryReadStream stream(_data, _dataSize, DisposeAfterUse::NO);
|
||||
|
||||
uint32 objectMapOffs = 0, sceneInfosOffs = 0;
|
||||
_objectMapCount = 0;
|
||||
|
||||
if (resource->_gameId == kGameIdBBDOU) {
|
||||
sceneInfosOffs = 0x18;
|
||||
} else if (resource->_gameId == kGameIdDuckman) {
|
||||
for (uint i = 0; i < 27; ++i) {
|
||||
_soundIds[i] = stream.readUint32LE();
|
||||
}
|
||||
sceneInfosOffs = 0x8C;
|
||||
}
|
||||
|
||||
stream.skip(4); // Skip unused
|
||||
|
||||
// Read item counts
|
||||
uint propertiesCount = stream.readUint16LE();
|
||||
uint blockCountersCount = stream.readUint16LE();
|
||||
if (resource->_gameId == kGameIdDuckman)
|
||||
_objectMapCount = stream.readUint16LE();
|
||||
_codeCount = stream.readUint16LE();
|
||||
_sceneInfosCount = stream.readUint16LE();
|
||||
if (resource->_gameId == kGameIdDuckman)
|
||||
stream.readUint16LE();//Unused?
|
||||
|
||||
// Read item offsets
|
||||
uint32 propertiesOffs = stream.readUint32LE();
|
||||
uint32 blockCountersOffs = stream.readUint32LE();
|
||||
if (resource->_gameId == kGameIdDuckman)
|
||||
objectMapOffs = stream.readUint32LE(); //TODO Is this needed for BBDOU?
|
||||
uint32 codeTblOffs = stream.readUint32LE();
|
||||
|
||||
debug(2, "ScriptResource::load() propertiesCount: %d; blockCountersCount: %d; _codeCount: %d; _sceneInfosCount: %d; _objectMapCount: %d",
|
||||
propertiesCount, blockCountersCount, _codeCount, _sceneInfosCount, _objectMapCount);
|
||||
debug(2, "ScriptResource::load() propertiesOffs: %08X; blockCountersOffs: %08X; codeTblOffs: %08X; objectMapOffs: %08X",
|
||||
propertiesOffs, blockCountersOffs, codeTblOffs, objectMapOffs);
|
||||
// Init properties
|
||||
_properties.init(propertiesCount, _data + propertiesOffs);
|
||||
|
||||
// Init blockcounters
|
||||
_blockCounters.init(blockCountersCount, _data + blockCountersOffs);
|
||||
|
||||
_codeOffsets = new uint32[_codeCount];
|
||||
stream.seek(codeTblOffs);
|
||||
for (uint i = 0; i < _codeCount; ++i) {
|
||||
_codeOffsets[i] = stream.readUint32LE();
|
||||
}
|
||||
|
||||
_sceneInfos = new SceneInfo[_sceneInfosCount];
|
||||
for (uint i = 0; i < _sceneInfosCount; ++i) {
|
||||
stream.seek(sceneInfosOffs + i * 4);
|
||||
uint32 sceneInfoOffs = stream.readUint32LE();
|
||||
stream.seek(sceneInfoOffs);
|
||||
_sceneInfos[i].load(_data, stream);
|
||||
}
|
||||
|
||||
if (_objectMapCount > 0) {
|
||||
_objectMap = new uint32[_objectMapCount];
|
||||
stream.seek(objectMapOffs);
|
||||
for (uint i = 0; i < _objectMapCount; ++i) {
|
||||
_objectMap[i] = stream.readUint32LE();
|
||||
stream.skip(4);
|
||||
}
|
||||
}
|
||||
|
||||
if (resource->_gameId == kGameIdDuckman) {
|
||||
stream.seek(0x6C);
|
||||
_mainActorObjectId = stream.readUint32LE();
|
||||
} else if (resource->_gameId == kGameIdBBDOU) {
|
||||
stream.seek(0);
|
||||
_mainActorObjectId = stream.readUint32LE();
|
||||
}
|
||||
|
||||
if (resource->_gameId == kGameIdDuckman)
|
||||
fixupSceneInfosDuckman();
|
||||
|
||||
}
|
||||
|
||||
byte *ScriptResource::getThreadCode(uint32 threadId) {
|
||||
return _data + _codeOffsets[(threadId & 0xFFFF) - 1];
|
||||
}
|
||||
|
||||
byte *ScriptResource::getCode(uint32 codeOffs) {
|
||||
return _data + codeOffs;
|
||||
}
|
||||
|
||||
SceneInfo *ScriptResource::getSceneInfo(uint32 index) {
|
||||
if (index > 0 && index <= _sceneInfosCount)
|
||||
return &_sceneInfos[index - 1];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32 ScriptResource::getObjectActorTypeId(uint32 objectId) {
|
||||
return _objectMap[(objectId & 0xFFFF) - 1];
|
||||
}
|
||||
|
||||
void ScriptResource::fixupSceneInfosDuckman() {
|
||||
for (uint i = 0; i < _sceneInfosCount; ++i) {
|
||||
_sceneInfos[i].fixupSceneInfosDuckman();
|
||||
}
|
||||
}
|
||||
|
||||
// ScriptInstance
|
||||
|
||||
ScriptInstance::ScriptInstance(IllusionsEngine *vm)
|
||||
: _vm(vm) {
|
||||
}
|
||||
|
||||
void ScriptInstance::load(Resource *resource) {
|
||||
_vm->_scriptResource = new ScriptResource();
|
||||
_vm->_scriptResource->load(resource);
|
||||
}
|
||||
|
||||
void ScriptInstance::unload() {
|
||||
delete _vm->_scriptResource;
|
||||
_vm->_scriptResource = nullptr;
|
||||
}
|
||||
|
||||
} // End of namespace Illusions
|
||||
152
engines/illusions/resources/scriptresource.h
Normal file
152
engines/illusions/resources/scriptresource.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ILLUSIONS_SCRIPTRESOURCE_H
|
||||
#define ILLUSIONS_SCRIPTRESOURCE_H
|
||||
|
||||
#include "illusions/resourcesystem.h"
|
||||
#include "common/file.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
class IllusionsEngine;
|
||||
|
||||
class ScriptResourceLoader : public BaseResourceLoader {
|
||||
public:
|
||||
ScriptResourceLoader(IllusionsEngine *vm) : _vm(vm) {}
|
||||
~ScriptResourceLoader() override {}
|
||||
void load(Resource *resource) override;
|
||||
bool isFlag(int flag) override;
|
||||
protected:
|
||||
IllusionsEngine *_vm;
|
||||
};
|
||||
|
||||
class Properties {
|
||||
public:
|
||||
Properties();
|
||||
void init(uint count, byte *properties);
|
||||
void clear();
|
||||
bool get(uint32 propertyId);
|
||||
void set(uint32 propertyId, bool value);
|
||||
uint32 getSize();
|
||||
void writeToStream(Common::WriteStream *out);
|
||||
bool readFromStream(Common::ReadStream *in);
|
||||
public:
|
||||
uint _count;
|
||||
byte *_properties;
|
||||
void getProperyPos(uint32 propertyId, uint &index, byte &mask);
|
||||
};
|
||||
|
||||
class BlockCounters {
|
||||
public:
|
||||
BlockCounters();
|
||||
void init(uint count, byte *blockCounters);
|
||||
void clear();
|
||||
byte get(uint index);
|
||||
void set(uint index, byte value);
|
||||
byte getC0(uint index);
|
||||
void setC0(uint index, byte value);
|
||||
uint32 getSize();
|
||||
void writeToStream(Common::WriteStream *out);
|
||||
bool readFromStream(Common::ReadStream *in);
|
||||
public:
|
||||
uint _count;
|
||||
byte *_blockCounters;
|
||||
};
|
||||
|
||||
struct TriggerCause {
|
||||
uint32 _verbId;
|
||||
uint32 _objectId2;
|
||||
uint32 _codeOffs;
|
||||
void load(Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
class TriggerObject {
|
||||
public:
|
||||
TriggerObject();
|
||||
~TriggerObject();
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
bool findTriggerCause(uint32 verbId, uint32 objectId2, uint32 &codeOffs);
|
||||
void fixupSceneInfosDuckman();
|
||||
public:
|
||||
uint32 _objectId;
|
||||
uint _causesCount;
|
||||
TriggerCause *_causes;
|
||||
};
|
||||
|
||||
class SceneInfo {
|
||||
public:
|
||||
SceneInfo();
|
||||
~SceneInfo();
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
bool findTriggerCause(uint32 verbId, uint32 objectId2, uint32 objectId, uint32 &codeOffs);
|
||||
void getResources(uint &resourcesCount, uint32 *&resources);
|
||||
void fixupSceneInfosDuckman();
|
||||
protected:
|
||||
uint16 _id;
|
||||
uint16 _unk;
|
||||
uint16 *_name;
|
||||
uint _triggerObjectsCount;
|
||||
TriggerObject *_triggerObjects;
|
||||
uint _resourcesCount;
|
||||
uint32 *_resources;
|
||||
TriggerObject *findTriggerObject(uint32 objectId);
|
||||
};
|
||||
|
||||
class ScriptResource {
|
||||
public:
|
||||
ScriptResource();
|
||||
~ScriptResource();
|
||||
void load(Resource *resource);
|
||||
byte *getThreadCode(uint32 threadId);
|
||||
byte *getCode(uint32 codeOffs);
|
||||
SceneInfo *getSceneInfo(uint32 index);
|
||||
uint32 getObjectActorTypeId(uint32 objectId);
|
||||
uint32 getMainActorObjectId() const { return _mainActorObjectId; }
|
||||
public:
|
||||
byte *_data;
|
||||
uint32 _dataSize;
|
||||
Properties _properties;
|
||||
BlockCounters _blockCounters;
|
||||
uint _codeCount;
|
||||
uint32 *_codeOffsets;
|
||||
uint _sceneInfosCount;
|
||||
SceneInfo *_sceneInfos;
|
||||
// Duckman specific
|
||||
uint32 _soundIds[27];
|
||||
uint _objectMapCount;
|
||||
uint32 *_objectMap;
|
||||
uint32 _mainActorObjectId;
|
||||
void fixupSceneInfosDuckman();
|
||||
};
|
||||
|
||||
class ScriptInstance : public ResourceInstance {
|
||||
public:
|
||||
ScriptInstance(IllusionsEngine *vm);
|
||||
void load(Resource *resource) override;
|
||||
void unload() override;
|
||||
public:
|
||||
IllusionsEngine *_vm;
|
||||
};
|
||||
|
||||
} // End of namespace Illusions
|
||||
|
||||
#endif // ILLUSIONS_ACTORRESOURCE_H
|
||||
102
engines/illusions/resources/soundresource.cpp
Normal file
102
engines/illusions/resources/soundresource.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/* 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 "illusions/illusions.h"
|
||||
#include "illusions/resources/soundresource.h"
|
||||
#include "illusions/sound.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
// SoundGroupResourceLoader
|
||||
|
||||
void SoundGroupResourceLoader::load(Resource *resource) {
|
||||
SoundGroupInstance *soundGroupInstance = new SoundGroupInstance(_vm);
|
||||
soundGroupInstance->load(resource);
|
||||
resource->_instance = soundGroupInstance;
|
||||
}
|
||||
|
||||
bool SoundGroupResourceLoader::isFlag(int flag) {
|
||||
return
|
||||
flag == kRlfLoadFile/* ||
|
||||
flag == kRlfFreeDataAfterLoad*/;
|
||||
}
|
||||
|
||||
// SoundEffect
|
||||
|
||||
void SoundEffect::load(Common::SeekableReadStream &stream) {
|
||||
_soundEffectId = stream.readUint32LE();
|
||||
_looping = stream.readUint16LE() != 0;
|
||||
_field6 = stream.readUint16LE();
|
||||
_volume = stream.readUint16LE();
|
||||
_frequency = stream.readUint16LE();
|
||||
stream.skip(32 + 4); // Skip name
|
||||
debug(1, "SoundEffect::load() _soundEffectId: %08X, _looping: %d, _field6: %d, _volume: %d, _frequency: %d",
|
||||
_soundEffectId, _looping, _field6, _volume, _frequency);
|
||||
}
|
||||
|
||||
// SoundGroupResource
|
||||
|
||||
SoundGroupResource::SoundGroupResource()
|
||||
: _soundEffects(nullptr) {
|
||||
}
|
||||
|
||||
SoundGroupResource::~SoundGroupResource() {
|
||||
delete[] _soundEffects;
|
||||
}
|
||||
|
||||
void SoundGroupResource::load(byte *data, uint32 dataSize) {
|
||||
Common::MemoryReadStream stream(data, dataSize, DisposeAfterUse::NO);
|
||||
|
||||
stream.skip(4);
|
||||
_soundEffectsCount = stream.readUint16LE();
|
||||
stream.skip(2);
|
||||
uint32 soundEffectsOffs = stream.readUint32LE();
|
||||
debug(1, "_soundEffectsCount: %d; soundEffectsOffs: %08X", _soundEffectsCount, soundEffectsOffs);
|
||||
_soundEffects = new SoundEffect[_soundEffectsCount];
|
||||
stream.seek(soundEffectsOffs);
|
||||
for (uint i = 0; i < _soundEffectsCount; ++i) {
|
||||
_soundEffects[i].load(stream);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// SoundGroupInstance
|
||||
|
||||
SoundGroupInstance::SoundGroupInstance(IllusionsEngine *vm)
|
||||
: _vm(vm), _soundGroupResource(nullptr) {
|
||||
}
|
||||
|
||||
void SoundGroupInstance::load(Resource *resource) {
|
||||
_soundGroupResource = new SoundGroupResource();
|
||||
_soundGroupResource->load(resource->_data, resource->_dataSize);
|
||||
for (uint i = 0; i < _soundGroupResource->_soundEffectsCount; ++i) {
|
||||
SoundEffect *soundEffect = &_soundGroupResource->_soundEffects[i];
|
||||
_vm->_soundMan->loadSound(soundEffect->_soundEffectId, resource->_resId, soundEffect->_looping);
|
||||
}
|
||||
_resId = resource->_resId;
|
||||
}
|
||||
|
||||
void SoundGroupInstance::unload() {
|
||||
_vm->_soundMan->unloadSounds(_resId);
|
||||
delete _soundGroupResource;
|
||||
}
|
||||
|
||||
} // End of namespace Illusions
|
||||
74
engines/illusions/resources/soundresource.h
Normal file
74
engines/illusions/resources/soundresource.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ILLUSIONS_SOUNDRESOURCE_H
|
||||
#define ILLUSIONS_SOUNDRESOURCE_H
|
||||
|
||||
#include "illusions/graphics.h"
|
||||
#include "illusions/resourcesystem.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
class IllusionsEngine;
|
||||
|
||||
class SoundGroupResourceLoader : public BaseResourceLoader {
|
||||
public:
|
||||
SoundGroupResourceLoader(IllusionsEngine *vm) : _vm(vm) {}
|
||||
~SoundGroupResourceLoader() override {}
|
||||
void load(Resource *resource) override;
|
||||
bool isFlag(int flag) override;
|
||||
protected:
|
||||
IllusionsEngine *_vm;
|
||||
};
|
||||
|
||||
struct SoundEffect {
|
||||
uint32 _soundEffectId;
|
||||
bool _looping;
|
||||
int16 _field6;
|
||||
int16 _volume;
|
||||
int16 _frequency;
|
||||
void load(Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
class SoundGroupResource {
|
||||
public:
|
||||
SoundGroupResource();
|
||||
~SoundGroupResource();
|
||||
void load(byte *data, uint32 dataSize);
|
||||
public:
|
||||
uint _soundEffectsCount;
|
||||
SoundEffect *_soundEffects;
|
||||
};
|
||||
|
||||
class SoundGroupInstance : public ResourceInstance {
|
||||
public:
|
||||
SoundGroupInstance(IllusionsEngine *vm);
|
||||
void load(Resource *resource) override;
|
||||
void unload() override;
|
||||
public:
|
||||
IllusionsEngine *_vm;
|
||||
SoundGroupResource *_soundGroupResource;
|
||||
uint32 _resId;
|
||||
};
|
||||
|
||||
} // End of namespace Illusions
|
||||
|
||||
#endif // ILLUSIONS_SOUNDRESOURCE_H
|
||||
178
engines/illusions/resources/talkresource.cpp
Normal file
178
engines/illusions/resources/talkresource.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
/* 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 "illusions/illusions.h"
|
||||
#include "illusions/resources/talkresource.h"
|
||||
#include "illusions/dictionary.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
// TalkResourceLoader
|
||||
|
||||
void TalkResourceLoader::load(Resource *resource) {
|
||||
resource->_instance = _vm->_talkItems->createTalkInstance(resource);
|
||||
}
|
||||
|
||||
bool TalkResourceLoader::isFlag(int flag) {
|
||||
return
|
||||
flag == kRlfLoadFile;
|
||||
}
|
||||
|
||||
// TalkEntry
|
||||
|
||||
void TalkEntry::load(byte *dataStart, Common::SeekableReadStream &stream) {
|
||||
_talkId = stream.readUint32LE();
|
||||
stream.readUint32LE(); // Skip unknown
|
||||
uint32 textOffs = stream.readUint32LE();
|
||||
uint32 tblOffs = stream.readUint32LE();
|
||||
uint32 voiceNameOffs = stream.readUint32LE();
|
||||
_text = (uint16 *)(dataStart + textOffs);
|
||||
_tblPtr = dataStart + tblOffs;
|
||||
_voiceName = dataStart + voiceNameOffs;
|
||||
debug(0, "TalkEntry::load() _talkId: %08X; textOffs: %08X; tblOffs: %08X; voiceNameOffs: %08X",
|
||||
_talkId, textOffs, tblOffs, voiceNameOffs);
|
||||
|
||||
#if defined(SCUMM_BIG_ENDIAN)
|
||||
for (byte *ptr = (byte *)_text; *ptr != 0; ptr += 2) {
|
||||
WRITE_UINT16(ptr, SWAP_BYTES_16(READ_UINT16(ptr)));
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// TalkResource
|
||||
|
||||
TalkResource::TalkResource()
|
||||
: _talkEntriesCount(0), _talkEntries(nullptr) {
|
||||
}
|
||||
|
||||
TalkResource::~TalkResource() {
|
||||
delete[] _talkEntries;
|
||||
}
|
||||
|
||||
void TalkResource::load(byte *data, uint32 dataSize) {
|
||||
Common::MemoryReadStream stream(data, dataSize, DisposeAfterUse::NO);
|
||||
stream.skip(4); // Skip size
|
||||
_talkEntriesCount = stream.readUint16LE();
|
||||
stream.skip(2); // Skip padding
|
||||
_talkEntries = new TalkEntry[_talkEntriesCount];
|
||||
for (uint i = 0; i < _talkEntriesCount; ++i) {
|
||||
stream.seek(8 + i * 0x14);
|
||||
_talkEntries[i].load(data, stream);
|
||||
}
|
||||
}
|
||||
|
||||
// TalkInstance
|
||||
|
||||
TalkInstance::TalkInstance(IllusionsEngine *vm)
|
||||
: _vm(vm), _pauseCtr(0) {
|
||||
}
|
||||
|
||||
void TalkInstance::load(Resource *resource) {
|
||||
TalkResource *talkResource = new TalkResource();
|
||||
talkResource->load(resource->_data, resource->_dataSize);
|
||||
_talkRes = talkResource;
|
||||
_talkId = resource->_resId;
|
||||
_sceneId = resource->_sceneId;
|
||||
registerResources();
|
||||
}
|
||||
|
||||
void TalkInstance::unload() {
|
||||
unregisterResources();
|
||||
_vm->_talkItems->removeTalkInstance(this);
|
||||
delete _talkRes;
|
||||
}
|
||||
|
||||
void TalkInstance::pause() {
|
||||
++_pauseCtr;
|
||||
if (_pauseCtr == 1)
|
||||
unregisterResources();
|
||||
}
|
||||
|
||||
void TalkInstance::unpause() {
|
||||
--_pauseCtr;
|
||||
if (_pauseCtr == 0)
|
||||
registerResources();
|
||||
}
|
||||
|
||||
void TalkInstance::registerResources() {
|
||||
for (uint i = 0; i < _talkRes->_talkEntriesCount; ++i) {
|
||||
TalkEntry *talkEntry = &_talkRes->_talkEntries[i];
|
||||
_vm->_dict->addTalkEntry(talkEntry->_talkId, talkEntry);
|
||||
}
|
||||
}
|
||||
|
||||
void TalkInstance::unregisterResources() {
|
||||
for (uint i = 0; i < _talkRes->_talkEntriesCount; ++i) {
|
||||
TalkEntry *talkEntry = &_talkRes->_talkEntries[i];
|
||||
_vm->_dict->removeTalkEntry(talkEntry->_talkId);
|
||||
}
|
||||
}
|
||||
|
||||
// TalkInstanceList
|
||||
|
||||
TalkInstanceList::TalkInstanceList(IllusionsEngine *vm)
|
||||
: _vm(vm) {
|
||||
}
|
||||
|
||||
TalkInstanceList::~TalkInstanceList() {
|
||||
}
|
||||
|
||||
TalkInstance *TalkInstanceList::createTalkInstance(Resource *resource) {
|
||||
TalkInstance *talkInstance = new TalkInstance(_vm);
|
||||
talkInstance->load(resource);
|
||||
_items.push_back(talkInstance);
|
||||
return talkInstance;
|
||||
}
|
||||
|
||||
void TalkInstanceList::removeTalkInstance(TalkInstance *talkInstance) {
|
||||
_items.remove(talkInstance);
|
||||
}
|
||||
|
||||
TalkInstance *TalkInstanceList::findTalkItem(uint32 talkId) {
|
||||
for (auto &item : _items) {
|
||||
if (item->_talkId == talkId)
|
||||
return item;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TalkInstance *TalkInstanceList::findTalkItemBySceneId(uint32 sceneId) {
|
||||
for (auto &item : _items) {
|
||||
if (item->_sceneId == sceneId)
|
||||
return item;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TalkInstanceList::pauseBySceneId(uint32 sceneId) {
|
||||
TalkInstance *talkInstance = findTalkItemBySceneId(sceneId);
|
||||
if (talkInstance)
|
||||
talkInstance->pause();
|
||||
}
|
||||
|
||||
void TalkInstanceList::unpauseBySceneId(uint32 sceneId) {
|
||||
TalkInstance *talkInstance = findTalkItemBySceneId(sceneId);
|
||||
if (talkInstance)
|
||||
talkInstance->unpause();
|
||||
}
|
||||
|
||||
} // End of namespace Illusions
|
||||
98
engines/illusions/resources/talkresource.h
Normal file
98
engines/illusions/resources/talkresource.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ILLUSIONS_TALKRESOURCE_H
|
||||
#define ILLUSIONS_TALKRESOURCE_H
|
||||
|
||||
#include "illusions/graphics.h"
|
||||
#include "illusions/resourcesystem.h"
|
||||
|
||||
namespace Illusions {
|
||||
|
||||
class IllusionsEngine;
|
||||
|
||||
class TalkResourceLoader : public BaseResourceLoader {
|
||||
public:
|
||||
TalkResourceLoader(IllusionsEngine *vm) : _vm(vm) {}
|
||||
~TalkResourceLoader() override {}
|
||||
void load(Resource *resource) override;
|
||||
bool isFlag(int flag) override;
|
||||
protected:
|
||||
IllusionsEngine *_vm;
|
||||
};
|
||||
|
||||
struct TalkEntry {
|
||||
uint32 _talkId;
|
||||
//field_4 dd
|
||||
uint16 *_text;
|
||||
byte *_tblPtr;
|
||||
byte *_voiceName;
|
||||
void load(byte *dataStart, Common::SeekableReadStream &stream);
|
||||
};
|
||||
|
||||
class TalkResource {
|
||||
public:
|
||||
TalkResource();
|
||||
~TalkResource();
|
||||
void load(byte *data, uint32 dataSize);
|
||||
public:
|
||||
uint _talkEntriesCount;
|
||||
TalkEntry *_talkEntries;
|
||||
};
|
||||
|
||||
class TalkInstance : public ResourceInstance {
|
||||
public:
|
||||
TalkInstance(IllusionsEngine *vm);
|
||||
void load(Resource *resource) override;
|
||||
void unload() override;
|
||||
void pause() override;
|
||||
void unpause() override;
|
||||
public:
|
||||
IllusionsEngine *_vm;
|
||||
uint32 _talkId;
|
||||
uint32 _sceneId;
|
||||
TalkResource *_talkRes;
|
||||
int _pauseCtr;
|
||||
void registerResources();
|
||||
void unregisterResources();
|
||||
};
|
||||
|
||||
class TalkInstanceList {
|
||||
public:
|
||||
TalkInstanceList(IllusionsEngine *vm);
|
||||
~TalkInstanceList();
|
||||
TalkInstance *createTalkInstance(Resource *resource);
|
||||
void removeTalkInstance(TalkInstance *talkInstance);
|
||||
TalkInstance *findTalkItem(uint32 talkId);
|
||||
TalkInstance *findTalkItemBySceneId(uint32 sceneId);
|
||||
void pauseBySceneId(uint32 sceneId);
|
||||
void unpauseBySceneId(uint32 sceneId);
|
||||
//protected:
|
||||
public:
|
||||
typedef Common::List<TalkInstance*> Items;
|
||||
typedef Items::iterator ItemsIterator;
|
||||
IllusionsEngine *_vm;
|
||||
Items _items;
|
||||
};
|
||||
|
||||
} // End of namespace Illusions
|
||||
|
||||
#endif // ILLUSIONS_TALKRESOURCE_H
|
||||
Reference in New Issue
Block a user