NANCY: Migrate engine to Path

This commit is contained in:
Le Philousophe 2023-09-17 18:23:44 +02:00 committed by Eugene Sandulenko
parent aa5ad1f500
commit 1c2d757dbd
65 changed files with 252 additions and 211 deletions

View File

@ -53,7 +53,7 @@ protected:
uint16 _surfHeight = 0;
// Data for displaying images inside text; not supported yet
Common::String _imageName;
Common::Path _imageName;
Common::Array<uint16> _imageLineIDs;
Common::Array<Common::Rect> _imageSrcs;

View File

@ -512,7 +512,7 @@ bool ConversationSound::ConversationFlags::isSatisfied() const {
}
void ConversationVideo::init() {
if (!_decoder.loadFile(_videoName + ".avf")) {
if (!_decoder.loadFile(Common::Path(_videoName + ".avf"))) {
error("Couldn't load video file %s", _videoName.c_str());
}
@ -672,7 +672,7 @@ void ConversationCel::readData(Common::SeekableReadStream &stream) {
readFilenameArray(stream, _treeNames, 4);
Common::SeekableReadStream *xsheet = SearchMan.createReadStreamForMember(xsheetName);
Common::SeekableReadStream *xsheet = SearchMan.createReadStreamForMember(Common::Path(xsheetName));
// Read the xsheet and load all images into the arrays
// Completely unoptimized, the original engine uses a buffer
@ -689,7 +689,7 @@ void ConversationCel::readData(Common::SeekableReadStream &stream) {
_frameTime = xsheet->readUint16LE();
xsheet->skip(2);
_celNames.resize(4, Common::Array<Common::String>(numFrames));
_celNames.resize(4, Common::Array<Common::Path>(numFrames));
for (uint i = 0; i < numFrames; ++i) {
for (uint j = 0; j < _celNames.size(); ++j) {
readFilename(*xsheet, _celNames[j][i]);
@ -729,7 +729,7 @@ bool ConversationCel::isVideoDonePlaying() {
return _curFrame >= MIN<uint>(_lastFrame, _celNames[0].size()) && _nextFrameTime <= g_nancy->getTotalPlayTime();
}
ConversationCel::Cel &ConversationCel::loadCel(const Common::String &name, const Common::String &treeName) {
ConversationCel::Cel &ConversationCel::loadCel(const Common::Path &name, const Common::String &treeName) {
// Assumes head and body cels will be named differently
if (_celCache.contains(name)) {
return _celCache[name];

View File

@ -141,7 +141,7 @@ protected:
Common::String getRecordTypeName() const override;
Common::String _videoName;
Common::String _paletteName;
Common::Path _paletteName;
uint _videoFormat = kLargeVideoFormat;
uint16 _firstFrame = 0;
int16 _lastFrame = 0;
@ -184,9 +184,9 @@ protected:
static const byte kCelOverrideTreeRectsOn = 2;
bool isVideoDonePlaying() override;
Cel &loadCel(const Common::String &name, const Common::String &treeName);
Cel &loadCel(const Common::Path &name, const Common::String &treeName);
Common::Array<Common::Array<Common::String>> _celNames;
Common::Array<Common::Array<Common::Path>> _celNames;
Common::Array<Common::String> _treeNames;
uint16 _frameTime = 0;
@ -205,7 +205,7 @@ protected:
Common::Array<RenderedCel> _celRObjects;
Common::HashMap<Common::String, Cel> _celCache;
Common::HashMap<Common::Path, Cel, Common::Path::IgnoreCase_Hash, Common::Path::IgnoreCase_EqualTo> _celCache;
Common::SharedPtr<ConversationCelLoader> _loaderPtr;
};

View File

@ -67,7 +67,7 @@ public:
void init() override;
uint16 _objectID = 0;
Common::String _imageName;
Common::Path _imageName;
Common::Array<FrameBlitDescription> _blitDescriptions;
int16 _drawnFrameID = -1;

View File

@ -38,7 +38,7 @@ namespace Action {
void Overlay::init() {
// Autotext overlays need special handling when blitting
if (_imageName.hasPrefix("USE_")) {
if (_imageName.baseName().hasPrefix("USE_")) {
_usesAutotext = true;
}

View File

@ -52,7 +52,7 @@ public:
void readData(Common::SeekableReadStream &stream) override;
void execute() override;
Common::String _imageName;
Common::Path _imageName;
uint16 _transparency = kPlayOverlayPlain;
uint16 _hasSceneChange = kPlayOverlaySceneChange;

View File

@ -60,7 +60,7 @@ protected:
int curRotation = 0;
};
Common::String _imageName;
Common::Path _imageName;
uint16 _height = 0;

View File

@ -43,7 +43,7 @@ protected:
Common::String getRecordTypeName() const override { return "BBallPuzzle"; };
bool isViewportRelative() const override { return true; }
Common::String _imageName;
Common::Path _imageName;
uint16 _positions = 0;
uint16 _powers = 0;

View File

@ -43,7 +43,7 @@ protected:
Common::String getRecordTypeName() const override { return "BombPuzzle"; }
bool isViewportRelative() const override { return true; }
Common::String _imageName;
Common::Path _imageName;
Common::Array<Common::Rect> _wireSrcs;
Common::Array<Common::Rect> _wireDests;
Common::Array<Common::Rect> _digitSrcs;

View File

@ -49,7 +49,7 @@ protected:
Common::String getRecordTypeName() const override { return "BulPuzzle"; }
bool isViewportRelative() const override { return true; }
Common::String _imageName;
Common::Path _imageName;
uint16 _numCells = 0;
uint16 _numPieces = 0;

View File

@ -73,7 +73,7 @@ protected:
Common::Rect getScreenPosition(Common::Point gridPos);
void drawGrid();
Common::String _imageName;
Common::Path _imageName;
Common::Array<Common::Array<uint16>> _grid;
Common::Array<Common::Point> _startLocations;

View File

@ -49,7 +49,7 @@ protected:
void rotateBase(int dir);
Common::String _imageName;
Common::Path _imageName;
Common::Rect _cwCursorDest;
Common::Rect _ccwCursorDest;

View File

@ -39,7 +39,7 @@ public:
void execute() override;
void handleInput(NancyInput &input) override;
Common::String _imageName;
Common::Path _imageName;
Common::Array<Common::Array<Common::Rect>> _srcRects;
Common::Array<Common::Rect> _destRects;
Common::Array<byte> _correctSequence;

View File

@ -69,7 +69,7 @@ protected:
bool canMove(uint pieceID, WallType direction);
void reset();
Common::String _imageName;
Common::Path _imageName;
Common::Point _exitPos = Common::Point(-1, -1);

View File

@ -45,7 +45,7 @@ protected:
Common::String getRecordTypeName() const override { return "MouseLightPuzzle"; };
bool isViewportRelative() const override { return true; }
Common::String _imageName;
Common::Path _imageName;
byte _radius = 0;
bool _smoothEdges = false;

View File

@ -58,7 +58,7 @@ protected:
void popUp(uint id);
void clearAllElements();
Common::String _imageName;
Common::Path _imageName;
bool _hasSecondState = false;
bool _itemsStayDown = true;
bool _needButtonToCheckSuccess = false;

View File

@ -52,7 +52,7 @@ protected:
enum SolveState { kNotSolved, kSolved };
Common::String _imageName;
Common::Path _imageName;
byte _popButtons = kButtonsStayDown;
byte _randomizeLights = kLightsCircular;

View File

@ -40,7 +40,7 @@ void PeepholePuzzle::init() {
g_nancy->_resource->loadImage(_innerImageName, _innerImage);
if (!_buttonsImageName.size()) {
if (_buttonsImageName.empty()) {
// Empty image name for buttons, use other image as source
_buttonsImage.create(_innerImage, _innerImage.getBounds());
} else {

View File

@ -47,8 +47,8 @@ protected:
void drawInner();
void checkButtons();
Common::String _innerImageName;
Common::String _buttonsImageName;
Common::Path _innerImageName;
Common::Path _buttonsImageName;
uint16 _transparency = 0;

View File

@ -1434,7 +1434,7 @@ void RaycastPuzzle::updateMap() {
}
}
void RaycastPuzzle::createTextureLightSourcing(Common::Array<Graphics::ManagedSurface> *array, const Common::String &textureName) {
void RaycastPuzzle::createTextureLightSourcing(Common::Array<Graphics::ManagedSurface> *array, const Common::Path &textureName) {
Graphics::PixelFormat format = g_nancy->_graphicsManager->getInputPixelFormat();
array->resize(8);

View File

@ -55,7 +55,7 @@ protected:
void validateMap();
void createTextureLightSourcing(Common::Array<Graphics::ManagedSurface> *array, const Common::String &textureName);
void createTextureLightSourcing(Common::Array<Graphics::ManagedSurface> *array, const Common::Path &textureName);
void drawMap();
void updateMap();

View File

@ -43,7 +43,7 @@ public:
void execute() override;
void handleInput(NancyInput &input) override;
Common::String _imageName;
Common::Path _imageName;
Common::Array<Common::Rect> _srcRects;
Common::Array<Common::Rect> _destRects;
Common::Rect _rotateHotspot;

View File

@ -39,7 +39,7 @@ public:
void execute() override;
void handleInput(NancyInput &input) override;
Common::String _imageName;
Common::Path _imageName;
Common::Array<Common::Rect> _srcRects;
Common::Array<Common::Rect> _destRects;
Common::Array<Common::Rect> _upHotspots;

View File

@ -63,7 +63,7 @@ void SafeDialPuzzle::updateGraphics() {
}
if (_animState == kReset && _nextAnim < g_nancy->getTotalPlayTime()) {
if (_resetImageName.size()) {
if (!_resetImageName.empty()) {
_animState = kResetAnim;
} else {
_animState = kNone;
@ -92,7 +92,7 @@ void SafeDialPuzzle::readData(Common::SeekableReadStream &stream) {
readFilename(stream, _imageName2);
readFilename(stream, _resetImageName);
_numInbetweens = (_imageName2.size() ? 1 : 0);
_numInbetweens = (!_imageName2.empty() ? 1 : 0);
uint16 num = 10;
if (g_nancy->getGameType() >= kGameTypeNancy4) {
@ -297,7 +297,7 @@ void SafeDialPuzzle::handleInput(NancyInput &input) {
void SafeDialPuzzle::drawDialFrame(uint frame) {
debug("%u", frame);
if (frame >= _dialSrcs.size() / 2 && _imageName2.size()) {
if (frame >= _dialSrcs.size() / 2 && !_imageName2.empty()) {
_drawSurface.blitFrom(_image2, _dialSrcs[frame], _dialDest);
} else {
_drawSurface.blitFrom(_image1, _dialSrcs[frame], _dialDest);

View File

@ -49,9 +49,9 @@ protected:
void drawDialFrame(uint frame);
void pushSequence(uint id);
Common::String _imageName1;
Common::String _imageName2;
Common::String _resetImageName;
Common::Path _imageName1;
Common::Path _imageName2;
Common::Path _resetImageName;
bool _enableWraparound = true;

View File

@ -46,7 +46,7 @@ protected:
void drawTime(uint16 hours, uint16 minutes);
Common::String _imageName;
Common::Path _imageName;
Common::Rect _minutesDest;
Common::Rect _hoursDest;

View File

@ -46,7 +46,7 @@ public:
const SPUZ *_spuzData = nullptr;
SliderPuzzleData *_puzzleState = nullptr;
Common::String _imageName;
Common::Path _imageName;
uint16 _width = 0;
uint16 _height = 0;
Common::Array<Common::Array<Common::Rect>> _srcRects;

View File

@ -48,7 +48,7 @@ public:
void execute() override;
void handleInput(NancyInput &input) override;
Common::String _imageName;
Common::Path _imageName;
Common::Rect _buttonSrc;
Common::Rect _buttonDest;

View File

@ -78,8 +78,8 @@ protected:
bool checkBuffer(const Tile &tile) const;
Common::String _tileImageName;
Common::String _maskImageName;
Common::Path _tileImageName;
Common::Path _maskImageName;
Common::Array<Common::Rect> _tileSrcs;
Common::Array<Common::Rect> _tileDests;

View File

@ -52,7 +52,7 @@ public:
void execute() override;
void handleInput(NancyInput &input) override;
Common::String _imageName;
Common::Path _imageName;
Common::Array<Common::Rect> _srcRects;
Common::Array<Common::Rect> _destRects;
SoundDescription _genericDialogueSound;

View File

@ -49,7 +49,7 @@ protected:
void drawRing(uint poleID, uint position, uint ringID, bool clear = false);
Common::String _imageName;
Common::Path _imageName;
Common::Array<uint16> _numRingsByDifficulty;
Common::Array<Common::Rect> _droppedRingSrcs;

View File

@ -51,7 +51,7 @@ protected:
void drawObject(uint objectID, uint faceID, uint frameID);
void turnLogic(uint objectID);
Common::String _imageName;
Common::Path _imageName;
uint16 _numFaces = 0;
uint16 _numFramesPerTurn = 0;

View File

@ -44,7 +44,7 @@ protected:
Common::String getRecordTypeName() const override { return "TwoDialPuzzle"; }
bool isViewportRelative() const override { return true; }
Common::String _imageName;
Common::Path _imageName;
bool _isClockwise[2] = { false, false };
uint16 _startPositions[2] = { 0, 0 };

View File

@ -100,11 +100,11 @@ void PlaySecondaryMovie::init() {
}
if (!_decoder->isVideoLoaded()) {
if (!_decoder->loadFile(_videoName + (_videoType == kVideoPlaytypeAVF ? ".avf" : ".bik"))) {
error("Couldn't load video file %s", _videoName.c_str());
if (!_decoder->loadFile(_videoName.append(_videoType == kVideoPlaytypeAVF ? ".avf" : ".bik"))) {
error("Couldn't load video file %s", _videoName.toString().c_str());
}
if (_paletteName.size()) {
if (!_paletteName.empty()) {
GraphicsManager::loadSurfacePalette(_fullFrame, _paletteName);
GraphicsManager::loadSurfacePalette(_drawSurface, _paletteName);
}

View File

@ -64,9 +64,9 @@ public:
void readData(Common::SeekableReadStream &stream) override;
void execute() override;
Common::String _videoName;
Common::String _paletteName;
Common::String _bitmapOverlayName;
Common::Path _videoName;
Common::Path _paletteName;
Common::Path _bitmapOverlayName;
uint16 _videoType = kVideoPlaytypeAVF;
uint16 _videoFormat = kLargeVideoFormat;

View File

@ -38,8 +38,8 @@ void PlaySecondaryVideo::init() {
_decoder.close();
}
if (!_decoder.loadFile(_filename + ".avf")) {
error("Couldn't load video file %s", _filename.c_str());
if (!_decoder.loadFile(_filename.append(".avf"))) {
error("Couldn't load video file %s", _filename.toString().c_str());
}
// Every secondary video frame (in nancy1) plays exactly 12ms slower than what its metadata says.
@ -47,7 +47,7 @@ void PlaySecondaryVideo::init() {
_decoder.addFrameTime(12);
_drawSurface.create(_decoder.getWidth(), _decoder.getHeight(), g_nancy->_graphicsManager->getInputPixelFormat());
if (_paletteFilename.size()) {
if (!_paletteFilename.empty()) {
GraphicsManager::loadSurfacePalette(_fullFrame, _paletteFilename);
}
@ -103,7 +103,7 @@ void PlaySecondaryVideo::updateGraphics() {
if (_decoder.isPlaying()) {
if (_decoder.needsUpdate()) {
GraphicsManager::copyToManaged(*_decoder.decodeNextFrame(), _fullFrame, _paletteFilename.size(), _videoFormat == kSmallVideoFormat);
GraphicsManager::copyToManaged(*_decoder.decodeNextFrame(), _fullFrame, !_paletteFilename.empty(), _videoFormat == kSmallVideoFormat);
_needsRedraw = true;
}

View File

@ -50,9 +50,9 @@ public:
void readData(Common::SeekableReadStream &stream) override;
void execute() override;
Common::String _filename;
Common::String _paletteFilename;
// Common::String _bitmapOverlayFilename
Common::Path _filename;
Common::Path _paletteFilename;
// Common::Path _bitmapOverlayFilename
// TVD only
uint16 _videoFormat = kLargeVideoFormat;

View File

@ -67,7 +67,7 @@ static void syncCiftreeInfo(Common::Serializer &ser, CifInfo &info) {
uint nameSize = g_nancy->getGameType() <= kGameTypeNancy2 ? 9 : 33;
byte name[34];
if (ser.isSaving()) {
memcpy(name, info.name.c_str(), nameSize);
memcpy(name, info.name.toString('/').c_str(), nameSize);
name[nameSize] = 0;
}
@ -89,7 +89,7 @@ enum {
kHashMapSize = 1024
};
CifFile::CifFile(Common::SeekableReadStream *stream, const Common::String &name) {
CifFile::CifFile(Common::SeekableReadStream *stream, const Common::Path &name) {
assert(stream);
_stream = stream;
@ -126,7 +126,7 @@ Common::SeekableReadStream *CifFile::createReadStream() const {
}
if (!success) {
warning("Failed to read data for CifFile '%s'", _info.name.c_str());
warning("Failed to read data for CifFile '%s'", _info.name.toString().c_str());
delete[] buf;
_stream->clearErr();
return nullptr;
@ -140,7 +140,7 @@ Common::SeekableReadStream *CifFile::createReadStreamRaw() const {
byte *buf = new byte[size];
if (!_stream->seek(_info.dataOffset) || _stream->read(buf, size) < size) {
warning("Failed to read data for CifFile '%s'", _info.name.c_str());
warning("Failed to read data for CifFile '%s'", _info.name.toString().c_str());
}
return new Common::MemoryReadStream(buf, size, DisposeAfterUse::YES);
@ -148,7 +148,7 @@ Common::SeekableReadStream *CifFile::createReadStreamRaw() const {
bool CifFile::sync(Common::Serializer &ser) {
if (!ser.matchBytes("CIF FILE WayneSikes", 20)) {
warning("Invalid id string found in CifFile '%s'", _info.name.c_str());
warning("Invalid id string found in CifFile '%s'", _info.name.toString().c_str());
return false;
}
@ -163,7 +163,7 @@ bool CifFile::sync(Common::Serializer &ser) {
ser.syncAsUint16LE(ver);
if (ver != 0 && ver != 1) {
warning("Unsupported version %d found in CifFile '%s'", ver, _info.name.c_str());
warning("Unsupported version %d found in CifFile '%s'", ver, _info.name.toString().c_str());
return false;
}
@ -177,7 +177,7 @@ bool CifFile::sync(Common::Serializer &ser) {
return true;
}
CifTree::CifTree(Common::SeekableReadStream *stream, const Common::String &name) :
CifTree::CifTree(Common::SeekableReadStream *stream, const Common::Path &name) :
_stream(stream),
_name(name) {}
@ -185,12 +185,12 @@ CifTree::~CifTree() {
delete _stream;
}
const CifInfo &CifTree::getCifInfo(const Common::String &name) const {
const CifInfo &CifTree::getCifInfo(const Common::Path &name) const {
return _fileMap[name];
}
bool CifTree::hasFile(const Common::Path &path) const {
return _fileMap.contains(path.toString());
return _fileMap.contains(path);
}
int CifTree::listMembers(Common::ArchiveMemberList &list) const {
@ -214,7 +214,7 @@ Common::SeekableReadStream *CifTree::createReadStreamForMember(const Common::Pat
return nullptr;
}
const CifInfo &info = _fileMap[path.toString()];
const CifInfo &info = _fileMap[path];
byte *buf = new byte[info.size];
bool success = true;
@ -236,7 +236,7 @@ Common::SeekableReadStream *CifTree::createReadStreamForMember(const Common::Pat
}
if (!success) {
warning("Failed to read data for '%s' from CifTree '%s'", info.name.c_str(), _name.c_str());
warning("Failed to read data for '%s' from CifTree '%s'", info.name.toString().c_str(), _name.toString().c_str());
delete[] buf;
_stream->clearErr();
return nullptr;
@ -250,25 +250,28 @@ Common::SeekableReadStream *CifTree::createReadStreamRaw(const Common::Path &pat
return nullptr;
}
const CifInfo &info = _fileMap[path.toString()];
const CifInfo &info = _fileMap[path];
uint32 size = (info.comp == CifInfo::kResCompression ? info.compressedSize : info.size);
byte *buf = new byte[size];
if (!_stream->seek(info.dataOffset) || _stream->read(buf, size) < size) {
warning("Failed to read data for '%s' from CifTree '%s'", info.name.c_str(), _name.c_str());
warning("Failed to read data for '%s' from CifTree '%s'", info.name.toString().c_str(), _name.toString().c_str());
}
return new Common::MemoryReadStream(buf, size, DisposeAfterUse::YES);
}
CifTree *CifTree::makeCifTreeArchive(const Common::String &name, const Common::String &ext) {
auto *stream = SearchMan.createReadStreamForMember(name + '.' + ext);
Common::Path path(name);
path.appendInPlace('.' + ext);
auto *stream = SearchMan.createReadStreamForMember(path);
if (!stream) {
return nullptr;
}
CifTree *ret = new CifTree(stream, name + '.' + ext);
CifTree *ret = new CifTree(stream, path);
Common::Serializer ser(stream, nullptr);
if (!ret->sync(ser)) {
@ -281,7 +284,7 @@ CifTree *CifTree::makeCifTreeArchive(const Common::String &name, const Common::S
bool CifTree::sync(Common::Serializer &ser) {
if (!ser.matchBytes("CIF TREE WayneSikes", 20)) {
warning("Invalid id string found in CifTree '%s'", _name.c_str());
warning("Invalid id string found in CifTree '%s'", _name.toString().c_str());
return false;
}
@ -296,7 +299,7 @@ bool CifTree::sync(Common::Serializer &ser) {
ser.syncAsUint16LE(ver);
if (ver != 0 && ver != 1) {
warning("Unsupported version %d found in CifTree '%s'", ver, _name.c_str());
warning("Unsupported version %d found in CifTree '%s'", ver, _name.toString().c_str());
return false;
}
@ -336,8 +339,8 @@ bool PatchTree::hasFile(const Common::Path &path) const {
for (auto &assoc : _associations) {
auto &confManProps = assoc.first;
auto &filenames = assoc.second;
for (const Common::String &s : filenames) {
if (s == path.toString()) {
for (const Common::Path &s : filenames) {
if (s == path) {
bool satisfied = true;
for (uint i = 0; i < confManProps.size(); ++i) {

View File

@ -47,7 +47,7 @@ struct CifInfo {
kResCompression = 2
};
Common::String name;
Common::Path name;
ResType type = kResTypeEmpty; // ResType
ResCompression comp = kResCompressionNone; // ResCompression
uint16 width = 0, pitch = 0, height = 0;
@ -64,7 +64,7 @@ private:
friend class ResourceManager;
CifFile() : _stream(nullptr) {}
public:
CifFile(Common::SeekableReadStream *stream, const Common::String &name);
CifFile(Common::SeekableReadStream *stream, const Common::Path &name);
~CifFile();
Common::SeekableReadStream *createReadStream() const;
@ -82,12 +82,12 @@ class CifTree : public Common::Archive {
protected:
friend class ResourceManager;
CifTree() : _stream(nullptr) {}
CifTree(Common::SeekableReadStream *stream, const Common::String &name);
CifTree(Common::SeekableReadStream *stream, const Common::Path &name);
virtual ~CifTree();
public:
// Used for extracting additional image data for conversation cels (nancy2 and up)
const CifInfo &getCifInfo(const Common::String &name) const;
const CifInfo &getCifInfo(const Common::Path &name) const;
// Archive interface
bool hasFile(const Common::Path &path) const override;
@ -96,7 +96,7 @@ public:
const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
Common::String getName() const { return _name; }
Common::Path getName() const { return _name; }
static CifTree *makeCifTreeArchive(const Common::String &name, const Common::String &ext);
@ -104,21 +104,21 @@ private:
bool sync(Common::Serializer &ser);
Common::SeekableReadStream *createReadStreamRaw(const Common::Path &path) const;
Common::String _name;
Common::Path _name;
Common::SeekableReadStream *_stream;
Common::HashMap<Common::String, CifInfo, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _fileMap;
Common::HashMap<Common::Path, CifInfo, Common::Path::IgnoreCase_Hash, Common::Path::IgnoreCase_EqualTo> _fileMap;
Common::Array<CifInfo> _writeFileMap;
};
// Ciftree that only provides a file if a certain ConfMan flag is true. Used for handling game patches
class PatchTree : public CifTree {
public:
PatchTree(Common::SeekableReadStream *stream, const Common::String &name) : CifTree(stream, name) {}
PatchTree(Common::SeekableReadStream *stream, const Common::Path &name) : CifTree(stream, name) {}
virtual ~PatchTree() {}
bool hasFile(const Common::Path &path) const override;
Common::Array<Common::Pair<Common::Array<Common::Pair<Common::String, Common::String>>, Common::StringArray>> _associations;
Common::Array<Common::Pair<Common::Array<Common::Pair<Common::String, Common::String>>, Common::Array<Common::Path>>> _associations;
};
} // End of namespace Nancy

View File

@ -357,7 +357,7 @@ void StaticData::readData(Common::SeekableReadStream &stream, Common::Language l
byte *patchBuf = nullptr;
uint32 patchBufSize = 0;
Common::Array<Common::Array<Common::String>> confManProps;
Common::Array<Common::Array<Common::String>> fileIDs;
Common::Array<Common::Array<Common::Path>> fileIDs;
while (stream.pos() < endPos) {
uint32 nextSectionOffset = stream.readUint32LE();
@ -564,7 +564,7 @@ void StaticData::readData(Common::SeekableReadStream &stream, Common::Language l
num2 = stream.readUint16LE();
fileIDs[i].resize(num2);
for (uint j = 0; j < num2; ++j) {
fileIDs[i][j] = stream.readString();
fileIDs[i][j] = Common::Path(stream.readString());
}
}

View File

@ -81,7 +81,7 @@ void NancyConsole::postEnter() {
if (dec->loadFile(_videoFile)) {
Graphics::ManagedSurface surf;
if (_paletteFile.size()) {
if (!_paletteFile.empty()) {
GraphicsManager::loadSurfacePalette(surf, _paletteFile);
}
@ -98,7 +98,7 @@ void NancyConsole::postEnter() {
if (dec->needsUpdate()) {
const Graphics::Surface *frame = dec->decodeNextFrame();
if (frame) {
GraphicsManager::copyToManaged(*frame, surf, _paletteFile.size());
GraphicsManager::copyToManaged(*frame, surf, !_paletteFile.empty());
g_nancy->_graphicsManager->debugDrawToScreen(surf);
}
}
@ -108,7 +108,7 @@ void NancyConsole::postEnter() {
g_nancy->_graphicsManager->redrawAll();
} else {
debugPrintf("Failed to load '%s'\n", _videoFile.c_str());
debugPrintf("Failed to load '%s'\n", _videoFile.toString(Common::Path::kNativeSeparator).c_str());
}
_videoFile.clear();
@ -119,7 +119,7 @@ void NancyConsole::postEnter() {
if (!_imageFile.empty()) {
Graphics::ManagedSurface surf;
if (g_nancy->_resource->loadImage(_imageFile, surf)) {
if (_paletteFile.size()) {
if (!_paletteFile.empty()) {
GraphicsManager::loadSurfacePalette(surf, _paletteFile);
}
@ -141,7 +141,7 @@ void NancyConsole::postEnter() {
g_nancy->_graphicsManager->redrawAll();
} else {
debugPrintf("Failed to load image '%s'\n", _imageFile.c_str());
debugPrintf("Failed to load image '%s'\n", _imageFile.toString().c_str());
}
_imageFile.clear();
@ -173,7 +173,7 @@ bool NancyConsole::Cmd_ciftreeExport(int argc, const char **argv) {
return true;
}
Common::StringArray files;
Common::Array<Common::Path> files;
for (int i = 2; i < argc; ++i) {
files.push_back(argv[i]);
@ -193,10 +193,15 @@ bool NancyConsole::Cmd_cifList(int argc, const char **argv) {
return true;
}
Common::Array<Common::String> list;
Common::Array<Common::Path> list;
g_nancy->_resource->list((argc == 2 ? "" : argv[2]), list, (CifInfo::ResType)atoi(argv[1]));
debugPrintColumns(list);
Common::StringArray listStr;
listStr.resize(list.size());
for (unsigned int i = 0; i < list.size(); i++) {
listStr[i] = list[i].toString();
}
debugPrintColumns(listStr);
return true;
}
@ -251,7 +256,7 @@ bool NancyConsole::Cmd_chunkExport(int argc, const char **argv) {
filename += '_';
filename += argv[2];
filename += ".dat";
dumpfile.open(filename);
dumpfile.open(Common::Path(filename));
dumpfile.write(buf, size);
dumpfile.close();
delete iff;
@ -354,7 +359,7 @@ bool NancyConsole::Cmd_exportImage(int argc, const char **argv) {
Graphics::ManagedSurface surf;
if (g_nancy->_resource->loadImage(argv[1], surf)) {
Common::DumpFile f;
if (!f.open(Common::String(argv[1]) + ".bmp")) {
if (!f.open(Common::Path(argv[1]).appendInPlace(".bmp"))) {
debugPrintf("Couldn't open file for writing!");
return true;
@ -376,7 +381,7 @@ bool NancyConsole::Cmd_playVideo(int argc, const char **argv) {
}
_videoFile = argv[1];
_videoFile += ".avf";
_videoFile.appendInPlace(".avf");
_paletteFile = argv[2];
return cmdExit(0, nullptr);
} else {
@ -387,7 +392,7 @@ bool NancyConsole::Cmd_playVideo(int argc, const char **argv) {
}
_videoFile = argv[1];
_videoFile += ".avf";
_videoFile.appendInPlace(".avf");
return cmdExit(0, nullptr);
}
}
@ -412,7 +417,7 @@ bool NancyConsole::Cmd_playSound(int argc, const char **argv) {
}
Common::File *f = new Common::File;
if (!f->open(Common::String(argv[1]) + ".his")) {
if (!f->open(Common::Path(argv[1]).appendInPlace(".his"))) {
debugPrintf("Failed to open '%s.his'\n", argv[1]);
delete f;
return true;
@ -442,7 +447,7 @@ bool NancyConsole::Cmd_loadScene(int argc, const char **argv) {
return true;
}
Common::String sceneName = Common::String::format("S%s", argv[1]);
Common::Path sceneName(Common::String::format("S%s", argv[1]));
IFF *iff = g_nancy->_resource->loadIFF(sceneName);
if (!iff) {
debugPrintf("Invalid scene S%s\n", argv[1]);
@ -610,7 +615,7 @@ bool NancyConsole::Cmd_listActionRecords(int argc, const char **argv) {
Common::Queue<uint> unknownTypes;
Common::Queue<Common::String> unknownDescs;
Common::SeekableReadStream *chunk;
IFF *sceneIFF = g_nancy->_resource->loadIFF("S" + s);
IFF *sceneIFF = g_nancy->_resource->loadIFF(Common::Path("S" + s));
if (!sceneIFF) {
debugPrintf("Invalid scene S%s\n", argv[1]);
return true;
@ -692,15 +697,15 @@ bool NancyConsole::Cmd_scanForActionRecordType(int argc, const char **argv) {
}
}
Common::Array<Common::String> list;
Common::Array<Common::Path> list;
// Action records only appear in the ciftree and promotree
g_nancy->_resource->list("ciftree", list, CifInfo::kResTypeScript);
g_nancy->_resource->list("promotree", list, CifInfo::kResTypeScript);
char descBuf[0x30];
for (Common::String &cifName : list) {
Common::String name = cifName;
for (Common::Path &cifName : list) {
Common::String name = cifName.baseName();
if (name.hasSuffixIgnoreCase(".iff")) {
name = name.substr(0, name.size() - 4);
}
@ -734,7 +739,7 @@ bool NancyConsole::Cmd_scanForActionRecordType(int argc, const char **argv) {
chunk->seek(0);
chunk->read(descBuf, 0x30);
descBuf[0x2F] = '\0';
debugPrintf("%s: ACT chunk %u, %s\n", cifName.c_str(), num, descBuf);
debugPrintf("%s: ACT chunk %u, %s\n", cifName.toString().c_str(), num, descBuf);
}
++num;

View File

@ -71,9 +71,9 @@ private:
void printActionRecord(const Nancy::Action::ActionRecord *record, bool noDependencies = false);
void recursePrintDependencies(const Nancy::Action::DependencyRecord &record);
Common::String _videoFile;
Common::String _imageFile;
Common::String _paletteFile;
Common::Path _videoFile;
Common::Path _imageFile;
Common::Path _paletteFile;
};
} // End of namespace Nancy

View File

@ -355,7 +355,7 @@ CRED::CRED(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
readFilename(*chunkStream, imageName);
textNames.resize(isVampire ? 7 : 1);
for (Common::String &str : textNames) {
for (Common::Path &str : textNames) {
readFilename(*chunkStream, str);
}
@ -698,16 +698,17 @@ RCPR::RCPR(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
uColor10[1] = chunkStream->readByte();
uColor10[2] = chunkStream->readByte();
Common::String tmp;
Common::Path tmp;
while (chunkStream->pos() < chunkStream->size()) {
readFilename(*chunkStream, tmp);
if (tmp.hasPrefixIgnoreCase("Wall")) {
Common::String baseName(tmp.baseName());
if (baseName.hasPrefixIgnoreCase("Wall")) {
wallNames.push_back(tmp);
} else if (tmp.hasPrefixIgnoreCase("SpW")) {
} else if (baseName.hasPrefixIgnoreCase("SpW")) {
specialWallNames.push_back(tmp);
} else if (tmp.hasPrefixIgnoreCase("Ceil")) {
} else if (baseName.hasPrefixIgnoreCase("Ceil")) {
ceilingNames.push_back(tmp);
} else if (tmp.hasPrefixIgnoreCase("Floor")) {
} else if (baseName.hasPrefixIgnoreCase("Floor")) {
floorNames.push_back(tmp);
}
}

View File

@ -39,8 +39,8 @@ struct BSUM : public EngineData {
byte header[90];
Common::String conversationTextsFilename;
Common::String autotextFilename;
Common::Path conversationTextsFilename;
Common::Path autotextFilename;
// Game start section
SceneChangeDescription firstScene;
@ -132,8 +132,8 @@ struct INV : public EngineData {
uint16 captionAutoClearTime = 3000;
Common::String inventoryBoxIconsImageName;
Common::String inventoryCursorsImageName;
Common::Path inventoryBoxIconsImageName;
Common::Path inventoryCursorsImageName;
SoundDescription cantSound;
Common::String cantText;
@ -181,8 +181,8 @@ struct MAP : public EngineData {
MAP(Common::SeekableReadStream *chunkStream);
Common::Array<Common::String> mapNames;
Common::Array<Common::String> mapPaletteNames;
Common::Array<Common::Path> mapNames;
Common::Array<Common::Path> mapPaletteNames;
Common::Array<SoundDescription> sounds;
// Globe section, TVD only
@ -207,7 +207,7 @@ struct MAP : public EngineData {
struct HELP : public EngineData {
HELP(Common::SeekableReadStream *chunkStream);
Common::String imageName;
Common::Path imageName;
Common::Rect buttonDest;
Common::Rect buttonSrc;
Common::Rect buttonHoverSrc;
@ -217,8 +217,8 @@ struct HELP : public EngineData {
struct CRED : public EngineData {
CRED(Common::SeekableReadStream *chunkStream);
Common::String imageName;
Common::Array<Common::String> textNames;
Common::Path imageName;
Common::Array<Common::Path> textNames;
Common::Rect textScreenPosition;
uint16 updateTime;
uint16 pixelsToScroll;
@ -229,7 +229,7 @@ struct CRED : public EngineData {
struct MENU : public EngineData {
MENU(Common::SeekableReadStream *chunkStream);
Common::String _imageName;
Common::Path _imageName;
Common::Array<Common::Rect> _buttonDests;
Common::Array<Common::Rect> _buttonDownSrcs;
Common::Array<Common::Rect> _buttonHighlightSrcs;
@ -240,7 +240,7 @@ struct MENU : public EngineData {
struct SET : public EngineData {
SET(Common::SeekableReadStream *chunkStream);
Common::String _imageName;
Common::Path _imageName;
// Common::Rect _scrollbarsBounds
Common::Array<Common::Rect> _scrollbarBounds;
Common::Array<Common::Rect> _buttonDests;
@ -259,7 +259,7 @@ struct SET : public EngineData {
struct LOAD : public EngineData {
LOAD(Common::SeekableReadStream *chunkStream);
Common::String _imageName;
Common::Path _imageName;
int16 _mainFontID;
int16 _highlightFontID;
@ -291,7 +291,7 @@ struct LOAD : public EngineData {
Common::Rect _cancelButtonHighlightSrc;
Common::Rect _cancelButtonDisabledSrc;
Common::String _gameSavedPopup;
Common::Path _gameSavedPopup;
// Common::Rect _gameSavedBounds
};
@ -301,7 +301,7 @@ struct SDLG : public EngineData {
struct Dialog {
Dialog(Common::SeekableReadStream *chunkStream);
Common::String imageName;
Common::Path imageName;
Common::Rect yesDest;
Common::Rect noDest;
@ -421,17 +421,17 @@ struct RCPR : public EngineData {
byte transparentWallColor[3];
byte uColor10[3];
Common::Array<Common::String> wallNames;
Common::Array<Common::String> specialWallNames;
Common::Array<Common::String> ceilingNames;
Common::Array<Common::String> floorNames;
Common::Array<Common::Path> wallNames;
Common::Array<Common::Path> specialWallNames;
Common::Array<Common::Path> ceilingNames;
Common::Array<Common::Path> floorNames;
};
// Contains the name and dimensions of an image.
struct ImageChunk : public EngineData {
ImageChunk(Common::SeekableReadStream *chunkStream);
Common::String imageName;
Common::Path imageName;
uint16 width;
uint16 height;
};

View File

@ -34,7 +34,7 @@ void Font::read(Common::SeekableReadStream &stream) {
_fontHeight = 0;
uint16 numCharacters = 78;
Common::String imageName;
Common::Path imageName;
readFilename(stream, imageName);
g_nancy->_resource->loadImage(imageName, _image);

View File

@ -213,9 +213,9 @@ void GraphicsManager::suppressNextDraw() {
_isSuppressed = true;
}
void GraphicsManager::loadSurfacePalette(Graphics::ManagedSurface &inSurf, const Common::String paletteFilename, uint paletteStart, uint paletteSize) {
void GraphicsManager::loadSurfacePalette(Graphics::ManagedSurface &inSurf, const Common::Path &paletteFilename, uint paletteStart, uint paletteSize) {
Common::File f;
if (f.open(paletteFilename + ".bmp")) {
if (f.open(paletteFilename.append(".bmp"))) {
Image::BitmapDecoder dec;
if (dec.loadStream(f)) {
inSurf.setPalette(dec.getPalette(), paletteStart, paletteSize);

View File

@ -61,7 +61,7 @@ public:
void grabViewportObjects(Common::Array<RenderObject *> &inArray);
void screenshotScreen(Graphics::ManagedSurface &inSurf);
static void loadSurfacePalette(Graphics::ManagedSurface &inSurf, const Common::String paletteFilename, uint paletteStart = 0, uint paletteSize = 256);
static void loadSurfacePalette(Graphics::ManagedSurface &inSurf, const Common::Path &paletteFilename, uint paletteStart = 0, uint paletteSize = 256);
static void copyToManaged(const Graphics::Surface &src, Graphics::ManagedSurface &dst, bool verticalFlip = false, bool doubleSize = false);
static void copyToManaged(void *src, Graphics::ManagedSurface &dst, uint srcW, uint srcH, const Graphics::PixelFormat &format, bool verticalFlip = false, bool doubleSize = false);

View File

@ -375,7 +375,7 @@ void NancyEngine::pauseEngineIntern(bool pause) {
void NancyEngine::bootGameEngine() {
// Load paths
const Common::FSNode gameDataDir(ConfMan.get("path"));
const Common::FSNode gameDataDir(ConfMan.getPath("path"));
SearchMan.addSubDirectoryMatching(gameDataDir, "game");
SearchMan.addSubDirectoryMatching(gameDataDir, "datafiles");
SearchMan.addSubDirectoryMatching(gameDataDir, "ciftree");
@ -464,7 +464,7 @@ void NancyEngine::bootGameEngine() {
// Load convo texts and autotext
auto *bsum = GetEngineData(BSUM);
if (bsum && bsum->conversationTextsFilename.size() && bsum->autotextFilename.size()) {
if (bsum && !bsum->conversationTextsFilename.empty() && !bsum->autotextFilename.empty()) {
iff = _resource->loadIFF(bsum->conversationTextsFilename);
if (!iff) {
error("Could not load CONVO IFF");

View File

@ -95,7 +95,7 @@ void RenderObject::grabPalette(byte *colors, uint paletteStart, uint paletteSize
}
}
void RenderObject::setPalette(const Common::String &paletteName, uint paletteStart, uint paletteSize) {
void RenderObject::setPalette(const Common::Path &paletteName, uint paletteStart, uint paletteSize) {
GraphicsManager::loadSurfacePalette(_drawSurface, paletteName, paletteStart, paletteSize);
_needsRedraw = true;
}

View File

@ -52,7 +52,7 @@ public:
// Only used by The Vampire Diaries
void grabPalette(byte *colors, uint paletteStart = 0, uint paletteSize = 256);
void setPalette(const Common::String &paletteName, uint paletteStart = 0, uint paletteSize = 256);
void setPalette(const Common::Path &paletteName, uint paletteStart = 0, uint paletteSize = 256);
void setPalette(const byte *colors, uint paletteStart = 0, uint paletteSize = 256);
bool hasMoved() const { return _previousScreenPosition != _screenPosition; }

View File

@ -35,17 +35,18 @@ static char treePrefix[] = "_tree_";
namespace Nancy {
bool ResourceManager::loadImage(const Common::String &name, Graphics::ManagedSurface &surf, const Common::String treeName, Common::Rect *outSrc, Common::Rect *outDest) {
bool ResourceManager::loadImage(const Common::Path &name, Graphics::ManagedSurface &surf, const Common::String &treeName, Common::Rect *outSrc, Common::Rect *outDest) {
// Detect and load autotext surfaces
if (name.hasPrefixIgnoreCase("USE_")) {
Common::String baseName(name.baseName());
if (baseName.hasPrefixIgnoreCase("USE_")) {
int surfID = -1;
if (name.hasPrefixIgnoreCase("USE_AUTOTEXT")) {
surfID = name[12] - '1';
} else if (name.hasPrefixIgnoreCase("USE_AUTOJOURNAL")) { // nancy6/7
surfID = name.substr(15).asUint64() + 2;
} else if (name.hasPrefixIgnoreCase("USE_AUTOLIST")) { // nancy8
surfID = name.substr(12).asUint64() + 2;
if (baseName.hasPrefixIgnoreCase("USE_AUTOTEXT")) {
surfID = baseName[12] - '1';
} else if (baseName.hasPrefixIgnoreCase("USE_AUTOJOURNAL")) { // nancy6/7
surfID = baseName.substr(15).asUint64() + 2;
} else if (baseName.hasPrefixIgnoreCase("USE_AUTOLIST")) { // nancy8
surfID = baseName.substr(12).asUint64() + 2;
}
if (surfID >= 0) {
@ -59,7 +60,7 @@ bool ResourceManager::loadImage(const Common::String &name, Graphics::ManagedSur
// First, check for external .bmp (TVD only; can also be enabled via a hidden ConfMan option)
if (g_nancy->getGameType() == kGameTypeVampire || ConfMan.getBool("external_bmp", ConfMan.getActiveDomainName())) {
stream = SearchMan.createReadStreamForMember(name + ".bmp");
stream = SearchMan.createReadStreamForMember(name.append(".bmp"));
if (stream) {
// Found external image
Image::BitmapDecoder bmpDec;
@ -76,7 +77,7 @@ bool ResourceManager::loadImage(const Common::String &name, Graphics::ManagedSur
// Check for loose .cif images. This bypasses tree search even with a provided treeName
if (!stream) {
stream = SearchMan.createReadStreamForMember(name + ".cif");
stream = SearchMan.createReadStreamForMember(name.append(".cif"));
if (stream) {
// .cifs are compressed, so we need to extract
CifFile cifFile(stream, name); // cifFile takes ownership of the current stream
@ -93,16 +94,16 @@ bool ResourceManager::loadImage(const Common::String &name, Graphics::ManagedSur
upper.toUppercase();
const CifTree *tree = (const CifTree *)SearchMan.getArchive(treePrefix + upper);
stream = tree->createReadStreamForMember(name);
stream = tree->createReadStreamForMember(Common::Path(name));
info = tree->getCifInfo(name);
}
if (!stream) {
// Tree name was not provided, or lookup failed. Use SearchMan
stream = SearchMan.createReadStreamForMember(name);
stream = SearchMan.createReadStreamForMember(Common::Path(name));
if (!stream) {
warning("Couldn't open image file %s", name.c_str());
warning("Couldn't open image file %s", name.toString().c_str());
return false;
}
@ -112,7 +113,7 @@ bool ResourceManager::loadImage(const Common::String &name, Graphics::ManagedSur
// No provided tree name, check inside every loaded tree
Common::String upper = _cifTreeNames[i];
upper.toUppercase();
if (SearchMan.getArchive(treePrefix + upper)->hasFile(name)) {
if (SearchMan.getArchive(treePrefix + upper)->hasFile(Common::Path(name))) {
tree = (const CifTree *)SearchMan.getArchive(treePrefix + upper);
break;
}
@ -129,13 +130,13 @@ bool ResourceManager::loadImage(const Common::String &name, Graphics::ManagedSur
// Sanity checks
if (info.type != CifInfo::kResTypeImage) {
warning("Resource '%s' is not an image", name.c_str());
warning("Resource '%s' is not an image", name.toString().c_str());
delete stream;
return false;
}
if (info.depth != 16) {
warning("Image '%s' has unsupported depth %i", name.c_str(), info.depth);
warning("Image '%s' has unsupported depth %i", name.toString().c_str(), info.depth);
delete stream;
return false;
}
@ -166,9 +167,9 @@ bool ResourceManager::loadImage(const Common::String &name, Graphics::ManagedSur
return true;
}
IFF *ResourceManager::loadIFF(const Common::String &name) {
IFF *ResourceManager::loadIFF(const Common::Path &name) {
// First, try to load external .cif
Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(name + ".cif");
Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(name.append(".cif"));
if (stream) {
// .cifs are compressed, so we need to extract
CifFile cifFile(stream, name); // cifFile takes ownership of the current stream
@ -177,11 +178,11 @@ IFF *ResourceManager::loadIFF(const Common::String &name) {
if (!stream) {
// Then, look for external .iff. These are uncompressed
stream = SearchMan.createReadStreamForMember(name + ".iff");
stream = SearchMan.createReadStreamForMember(name.append(".iff"));
// Finally, look inside ciftrees
if (!stream) {
stream = SearchMan.createReadStreamForMember(name);
stream = SearchMan.createReadStreamForMember(Common::Path(name));
}
}
@ -213,7 +214,7 @@ PatchTree *ResourceManager::readPatchTree(Common::SeekableReadStream *stream, co
return nullptr;
}
PatchTree *tree = new PatchTree(stream, name);
PatchTree *tree = new PatchTree(stream, Common::Path(name));
Common::Serializer ser(stream, nullptr);
if (!tree->sync(ser)) {
@ -228,7 +229,7 @@ PatchTree *ResourceManager::readPatchTree(Common::SeekableReadStream *stream, co
return tree;
}
Common::String ResourceManager::getCifDescription(const Common::String &treeName, const Common::String &name) const {
Common::String ResourceManager::getCifDescription(const Common::String &treeName, const Common::Path &name) const {
const CifTree *tree = nullptr;
if (treeName.size()) {
Common::String upper = treeName;
@ -253,7 +254,7 @@ Common::String ResourceManager::getCifDescription(const Common::String &treeName
const CifInfo &info = tree->getCifInfo(name);
Common::String desc;
desc = Common::String::format("Name: %s\n", info.name.c_str());
desc = Common::String::format("Name: %s\n", info.name.toString().c_str());
desc += Common::String::format("Type: %i\n", info.type);
desc += Common::String::format("Compression: %i\n", info.comp);
desc += Common::String::format("Size: %i\n", info.size);
@ -266,7 +267,7 @@ Common::String ResourceManager::getCifDescription(const Common::String &treeName
return desc;
}
void ResourceManager::list(const Common::String &treeName, Common::StringArray &outList, CifInfo::ResType type) const {
void ResourceManager::list(const Common::String &treeName, Common::Array<Common::Path> &outList, CifInfo::ResType type) const {
if (treeName.size()) {
Common::String upper = treeName;
upper.toUppercase();
@ -294,14 +295,14 @@ void ResourceManager::list(const Common::String &treeName, Common::StringArray &
}
}
bool ResourceManager::exportCif(const Common::String &treeName, const Common::String &name) {
bool ResourceManager::exportCif(const Common::String &treeName, const Common::Path &name) {
if (!SearchMan.hasFile(name)) {
return false;
}
// First, look for a loose .cif file
CifInfo info;
Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(name + ".cif");
Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(name.append(".cif"));
if (stream) {
// .cifs are compressed, so we need to extract
CifFile cifFile(stream, name); // cifFile takes ownership of the current stream
@ -311,7 +312,7 @@ bool ResourceManager::exportCif(const Common::String &treeName, const Common::St
if (!stream) {
// Then, look for an external .iff. These are uncompressed
stream = SearchMan.createReadStreamForMember(name + ".iff");
stream = SearchMan.createReadStreamForMember(name.append(".iff"));
if (stream) {
info.comp = CifInfo::kResCompressionNone;
info.type = CifInfo::kResTypeScript;
@ -337,7 +338,7 @@ bool ResourceManager::exportCif(const Common::String &treeName, const Common::St
// would regularly not be in a ciftree (e.g. sounds)
stream = SearchMan.createReadStreamForMember(name);
if (!stream) {
warning("Couldn't open resource %s", name.c_str());
warning("Couldn't open resource %s", name.toString().c_str());
return false;
}
@ -353,7 +354,7 @@ bool ResourceManager::exportCif(const Common::String &treeName, const Common::St
file._info = info;
Common::DumpFile dump;
dump.open(name + ".cif");
dump.open(name.append(".cif"));
Common::Serializer ser(nullptr, &dump);
file.sync(ser);
@ -365,7 +366,7 @@ bool ResourceManager::exportCif(const Common::String &treeName, const Common::St
return true;
}
bool ResourceManager::exportCifTree(const Common::String &treeName, const Common::StringArray &names) {
bool ResourceManager::exportCifTree(const Common::String &treeName, const Common::Array<Common::Path> &names) {
Common::Array<Common::SeekableReadStream *> resStreams;
CifTree file;
@ -386,23 +387,24 @@ bool ResourceManager::exportCifTree(const Common::String &treeName, const Common
}
for (uint i = 0; i < names.size(); ++i) {
const Common::Path &path = names[i];
// First, look for loose .cif files
CifInfo info;
Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(names[i] + ".cif");
Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(path.append(".cif"));
if (stream) {
// .cifs are compressed, so we need to extract
CifFile cifFile(stream, names[i]); // cifFile takes ownership of the current stream
CifFile cifFile(stream, path); // cifFile takes ownership of the current stream
stream = cifFile.createReadStreamRaw();
info = cifFile._info;
}
if (!stream) {
// Then, look for external .iff. These are uncompressed
stream = SearchMan.createReadStreamForMember(names[i] + ".iff");
stream = SearchMan.createReadStreamForMember(path.append(".iff"));
if (stream) {
info.comp = CifInfo::kResCompressionNone;
info.type = CifInfo::kResTypeScript;
info.name = names[i];
info.name = path;
info.compressedSize = info.size = stream->size();
} else {
// Look inside ciftrees
@ -410,27 +412,27 @@ bool ResourceManager::exportCifTree(const Common::String &treeName, const Common
for (uint j = 0; j < _cifTreeNames.size(); ++j) {
Common::String upper = _cifTreeNames[j];
upper.toUppercase();
if (SearchMan.getArchive(treePrefix + upper)->hasFile(names[i])) {
if (SearchMan.getArchive(treePrefix + upper)->hasFile(path)) {
tree = (const CifTree *)SearchMan.getArchive(treePrefix + upper);
break;
}
}
if (tree) {
stream = tree->createReadStreamRaw(names[i]);
info = tree->getCifInfo(names[i]);
stream = tree->createReadStreamRaw(path);
info = tree->getCifInfo(path);
} else {
// Finally, use SearchMan to get a loose file. This is useful if we want to add files that
// would regularly not be in a ciftree (e.g. sounds)
stream = SearchMan.createReadStreamForMember(names[i]);
stream = SearchMan.createReadStreamForMember(path);
if (!stream) {
warning("Couldn't open resource %s", names[i].c_str());
warning("Couldn't open resource %s", path.toString().c_str());
continue;
}
info.comp = CifInfo::kResCompressionNone;
info.type = CifInfo::kResTypeScript;
info.name = names[i];
info.name = path;
info.compressedSize = info.size = stream->size();
}
}
@ -449,7 +451,7 @@ bool ResourceManager::exportCifTree(const Common::String &treeName, const Common
}
Common::DumpFile dump;
dump.open(treeName + ".dat");
dump.open(Common::Path(treeName + ".dat"));
Common::Serializer ser(nullptr, &dump);
file.sync(ser);

View File

@ -43,10 +43,10 @@ public:
// Load an image resource. Can be either external .bmp file, or raw image data embedded inside a ciftree
// Ciftree images may have additional data dictating how they need to be blitted on screen (see ConversationCel).
// This is accessed via the outSrc/outDest parameters.
bool loadImage(const Common::String &name, Graphics::ManagedSurface &surf, const Common::String treeName = "", Common::Rect *outSrc = nullptr, Common::Rect *outDest = nullptr);
bool loadImage(const Common::Path &name, Graphics::ManagedSurface &surf, const Common::String &treeName = Common::String(), Common::Rect *outSrc = nullptr, Common::Rect *outDest = nullptr);
// Loads a single IFF file. These can either be inside standalone .cif files, or embedded inside a ciftree
IFF *loadIFF(const Common::String &name);
IFF *loadIFF(const Common::Path &name);
// Load a new ciftree
bool readCifTree(const Common::String &name, const Common::String &ext, int priority);
@ -56,16 +56,16 @@ private:
// Debug functions
// Return a human-readable description of a single CIF file.
Common::String getCifDescription(const Common::String &treeName, const Common::String &name) const;
Common::String getCifDescription(const Common::String &treeName, const Common::Path &name) const;
// Return a list of all resources of a certain type (does not list external files)
void list(const Common::String &treeName, Common::StringArray &outList, CifInfo::ResType type) const;
void list(const Common::String &treeName, Common::Array<Common::Path> &outList, CifInfo::ResType type) const;
// Exports a single resource as a standalone .cif file
bool exportCif(const Common::String &treeName, const Common::String &name);
bool exportCif(const Common::String &treeName, const Common::Path &name);
// Exports a collection of resources as a ciftree
bool exportCifTree(const Common::String &treeName, const Common::StringArray &names);
bool exportCifTree(const Common::String &treeName, const Common::Array<Common::Path> &names);
private:
Common::Array<Common::String> _cifTreeNames;

View File

@ -303,7 +303,8 @@ void SoundManager::loadSound(const SoundDescription &description, SoundEffectDes
*effectData = nullptr;
}
Common::SeekableReadStream *file = SearchMan.createReadStreamForMember(description.name + (g_nancy->getGameType() == kGameTypeVampire ? ".dwd" : ".his"));
Common::Path path(description.name + (g_nancy->getGameType() == kGameTypeVampire ? ".dwd" : ".his"));
Common::SeekableReadStream *file = SearchMan.createReadStreamForMember(path);
if (file) {
_channels[description.channelID].stream = makeHISStream(file, DisposeAfterUse::YES, description.samplesPerSec);
}

View File

@ -231,7 +231,7 @@ void LoadSaveMenu::init() {
Common::Point(), g_nancy->_graphicsManager->getTransColor());
// Load the "Your game has been saved" popup graphic
if (_loadSaveData->_gameSavedPopup.size()) {
if (!_loadSaveData->_gameSavedPopup.empty()) {
g_nancy->_resource->loadImage(_loadSaveData->_gameSavedPopup, _successOverlay._drawSurface);
Common::Rect destBounds = Common::Rect(0,0, _successOverlay._drawSurface.w, _successOverlay._drawSurface.h);
destBounds.moveTo(640 / 2 - destBounds.width() / 2,

View File

@ -168,20 +168,20 @@ void Map::MapViewport::updateGraphics() {
}
}
void Map::MapViewport::loadVideo(const Common::String &filename, const Common::String &palette) {
void Map::MapViewport::loadVideo(const Common::Path &filename, const Common::Path &palette) {
if (_decoder.isVideoLoaded()) {
_decoder.close();
}
if (!_decoder.loadFile(filename + ".avf")) {
error("Couldn't load video file %s", filename.c_str());
if (!_decoder.loadFile(filename.append(".avf"))) {
error("Couldn't load video file %s", filename.toString().c_str());
}
if (palette.size()) {
if (!palette.empty()) {
setPalette(palette);
}
GraphicsManager::copyToManaged(*_decoder.decodeNextFrame(), _drawSurface, palette.size());
GraphicsManager::copyToManaged(*_decoder.decodeNextFrame(), _drawSurface, !palette.empty());
_needsRedraw = true;
}

View File

@ -63,7 +63,7 @@ protected:
void init() override;
void updateGraphics() override;
void loadVideo(const Common::String &filename, const Common::String &palette = Common::String());
void loadVideo(const Common::Path &filename, const Common::Path &palette = Common::Path());
void playVideo() { _decoder.start(); }
void unloadVideo() { _decoder.close(); }

View File

@ -852,11 +852,11 @@ void Scene::load(bool fromSaveFile) {
g_nancy->_graphicsManager->suppressNextDraw();
// Scene IDs are prefixed with S inside the cif tree; e.g 100 -> S100
Common::String sceneName = Common::String::format("S%u", _sceneState.nextScene.sceneID);
Common::Path sceneName(Common::String::format("S%u", _sceneState.nextScene.sceneID));
IFF *sceneIFF = g_nancy->_resource->loadIFF(sceneName);
if (!sceneIFF) {
error("Faled to load IFF %s", sceneName.c_str());
error("Faled to load IFF %s", sceneName.toString().c_str());
}
Common::SeekableReadStream *sceneSummaryChunk = sceneIFF->getChunkStream("SSUM");
@ -909,7 +909,7 @@ void Scene::load(bool fromSaveFile) {
_sceneState.currentScene.verticalOffset,
_sceneState.summary.panningType,
_sceneState.summary.videoFormat,
_sceneState.summary.palettes.size() ? _sceneState.summary.palettes[(byte)_sceneState.currentScene.paletteID] : Common::String());
_sceneState.summary.palettes.size() ? _sceneState.summary.palettes[(byte)_sceneState.currentScene.paletteID] : Common::Path());
if (_viewport.getFrameCount() <= 1) {
_viewport.disableEdges(kLeft | kRight);

View File

@ -79,10 +79,10 @@ public:
// SSUM and TSUM
// Default values set to match those applied when loading from a TSUM chunk
Common::String description;
Common::String videoFile;
Common::Path videoFile;
uint16 videoFormat = kLargeVideoFormat;
Common::Array<Common::String> palettes;
Common::Array<Common::Path> palettes;
SoundDescription sound;
byte panningType = kPan360;

View File

@ -134,7 +134,7 @@ void SetupMenu::init() {
if (g_nancy->getGameType() == kGameTypeVampire) {
// There is a setup.bmp an the top directory of the first disk,
// which we need to avoid
_background.init("ART/" + _setupData->_imageName);
_background.init(Common::Path("ART/").joinInPlace(_setupData->_imageName));
} else {
_background.init(_setupData->_imageName);
}

View File

@ -27,7 +27,7 @@
namespace Nancy {
namespace UI {
void FullScreenImage::init(const Common::String &imageName) {
void FullScreenImage::init(const Common::Path &imageName) {
g_nancy->_resource->loadImage(imageName, _drawSurface);
Common::Rect srcBounds = Common::Rect(0,0, _drawSurface.w, _drawSurface.h);

View File

@ -32,7 +32,7 @@ public:
FullScreenImage() : RenderObject(0) {}
virtual ~FullScreenImage() = default;
void init(const Common::String &imageName);
void init(const Common::Path &imageName);
protected:
void init() override {}

View File

@ -207,13 +207,13 @@ void Viewport::handleInput(NancyInput &input) {
_movementLastFrame = direction;
}
void Viewport::loadVideo(const Common::String &filename, uint frameNr, uint verticalScroll, byte panningType, uint16 format, const Common::String &palette) {
void Viewport::loadVideo(const Common::Path &filename, uint frameNr, uint verticalScroll, byte panningType, uint16 format, const Common::Path &palette) {
if (_decoder.isVideoLoaded()) {
_decoder.close();
}
if (!_decoder.loadFile(filename + ".avf")) {
error("Couldn't load video file %s", filename.c_str());
if (!_decoder.loadFile(filename.append(".avf"))) {
error("Couldn't load video file %s", filename.toString().c_str());
}
_videoFormat = format;
@ -225,7 +225,7 @@ void Viewport::loadVideo(const Common::String &filename, uint frameNr, uint vert
setFrame(frameNr);
setVerticalScroll(verticalScroll);
if (palette.size()) {
if (!palette.empty()) {
GraphicsManager::loadSurfacePalette(_fullFrame, palette);
setPalette(palette);
}

View File

@ -56,7 +56,7 @@ public:
void init() override;
void handleInput(NancyInput &input);
void loadVideo(const Common::String &filename, uint frameNr = 0, uint verticalScroll = 0, byte panningType = kPanNone, uint16 format = 2, const Common::String &palette = Common::String());
void loadVideo(const Common::Path &filename, uint frameNr = 0, uint verticalScroll = 0, byte panningType = kPanNone, uint16 format = 2, const Common::Path &palette = Common::Path());
void setFrame(uint frameNr);
void setNextFrame();

View File

@ -230,6 +230,23 @@ void readFilenameArray(Common::Serializer &stream, Common::Array<Common::String>
}
}
void readFilenameArray(Common::SeekableReadStream &stream, Common::Array<Common::Path> &inArray, uint num) {
inArray.resize(num);
for (Common::Path &str : inArray) {
readFilename(stream, str);
}
}
void readFilenameArray(Common::Serializer &stream, Common::Array<Common::Path> &inArray, uint num, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
Common::Serializer::Version version = stream.getVersion();
if (version >= minVersion && version <= maxVersion) {
inArray.resize(num);
for (Common::Path &str : inArray) {
readFilename(stream, str, minVersion, maxVersion);
}
}
}
// A text line will often be broken up into chunks separated by nulls, use
// this function to put it back together as a Common::String
void assembleTextLine(char *rawCaption, Common::String &output, uint size) {

View File

@ -38,8 +38,20 @@ void readRectArray16(Common::Serializer &stream, Common::Array<Common::Rect> &in
void readFilename(Common::SeekableReadStream &stream, Common::String &inString);
void readFilename(Common::Serializer &stream, Common::String &inString, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion);
inline void readFilename(Common::SeekableReadStream &stream, Common::Path &inPath) {
Common::String inString;
readFilename(stream, inString);
inPath = Common::Path(inString);
}
inline void readFilename(Common::Serializer &stream, Common::Path &inPath, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion) {
Common::String inString;
readFilename(stream, inString, minVersion, maxVersion);
inPath = Common::Path(inString);
}
void readFilenameArray(Common::SeekableReadStream &stream, Common::Array<Common::String> &inArray, uint num);
void readFilenameArray(Common::Serializer &stream, Common::Array<Common::String> &inArray, uint num, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion);
void readFilenameArray(Common::SeekableReadStream &stream, Common::Array<Common::Path> &inArray, uint num);
void readFilenameArray(Common::Serializer &stream, Common::Array<Common::Path> &inArray, uint num, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion);
void assembleTextLine(char *rawCaption, Common::String &output, uint size);