mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 05:38:56 +00:00
Added support for sound archives.
We initialize them in the DraciEngine constructor, but don't play any sounds yet. Checked that it works for all existing sound files (required several work-arounds against unspoken specification). When copying the interface from barchive.h, I decided to remove some const's from there, because getFile() wasn't really behaving like const. Removed some static Common::String instances. svn-id: r44953
This commit is contained in:
parent
b6baadff53
commit
c4563616ae
@ -268,10 +268,8 @@ void BArchive::closeArchive(void) {
|
||||
* @return Pointer to a BAFile coresponding to the opened file or NULL (on failure)
|
||||
*
|
||||
* Loads individual BAR files from an archive to memory on demand.
|
||||
* Should not be called directly. Instead, one should access files
|
||||
* through the operator[] interface.
|
||||
*/
|
||||
BAFile *BArchive::loadFileBAR(uint i) const {
|
||||
BAFile *BArchive::loadFileBAR(uint i) {
|
||||
Common::File f;
|
||||
|
||||
// Else open archive and read in requested file
|
||||
@ -310,7 +308,7 @@ BAFile *BArchive::loadFileBAR(uint i) const {
|
||||
* Should not be called directly. Instead, one should access files
|
||||
* through the operator[] interface.
|
||||
*/
|
||||
BAFile *BArchive::loadFileDFW(uint i) const {
|
||||
BAFile *BArchive::loadFileDFW(uint i) {
|
||||
Common::File f;
|
||||
byte *buf;
|
||||
|
||||
@ -390,7 +388,7 @@ void BArchive::clearCache() {
|
||||
}
|
||||
}
|
||||
|
||||
const BAFile *BArchive::getFile(uint i) const {
|
||||
const BAFile *BArchive::getFile(uint i) {
|
||||
// Check whether requested file exists
|
||||
if (i >= _fileCount) {
|
||||
return NULL;
|
||||
|
@ -71,7 +71,7 @@ public:
|
||||
|
||||
void clearCache();
|
||||
|
||||
const BAFile *getFile(uint i) const;
|
||||
const BAFile *getFile(uint i);
|
||||
|
||||
private:
|
||||
// Archive header data
|
||||
@ -89,8 +89,8 @@ private:
|
||||
bool _opened; ///< True if the archive is opened, false otherwise
|
||||
|
||||
void openDFW(const Common::String &path);
|
||||
BAFile *loadFileDFW(uint i) const;
|
||||
BAFile *loadFileBAR(uint i) const;
|
||||
BAFile *loadFileDFW(uint i);
|
||||
BAFile *loadFileBAR(uint i);
|
||||
};
|
||||
|
||||
} // End of namespace Draci
|
||||
|
@ -47,18 +47,20 @@ namespace Draci {
|
||||
|
||||
// Data file paths
|
||||
|
||||
const Common::String objectsPath("OBJEKTY.DFW");
|
||||
const Common::String palettePath("PALETY.DFW");
|
||||
const Common::String spritesPath("OBR_AN.DFW");
|
||||
const Common::String overlaysPath("OBR_MAS.DFW");
|
||||
const Common::String roomsPath("MIST.DFW");
|
||||
const Common::String animationsPath("ANIM.DFW");
|
||||
const Common::String iconsPath("HRA.DFW");
|
||||
const Common::String walkingMapsPath("MAPY.DFW");
|
||||
const Common::String itemsPath("IKONY.DFW");
|
||||
const Common::String itemImagesPath("OBR_IK.DFW");
|
||||
const Common::String initPath("INIT.DFW");
|
||||
const Common::String stringsPath("RETEZCE.DFW");
|
||||
const char *objectsPath = "OBJEKTY.DFW";
|
||||
const char *palettePath = "PALETY.DFW";
|
||||
const char *spritesPath = "OBR_AN.DFW";
|
||||
const char *overlaysPath = "OBR_MAS.DFW";
|
||||
const char *roomsPath = "MIST.DFW";
|
||||
const char *animationsPath = "ANIM.DFW";
|
||||
const char *iconsPath = "HRA.DFW";
|
||||
const char *walkingMapsPath = "MAPY.DFW";
|
||||
const char *itemsPath = "IKONY.DFW";
|
||||
const char *itemImagesPath = "OBR_IK.DFW";
|
||||
const char *initPath = "INIT.DFW";
|
||||
const char *stringsPath = "RETEZCE.DFW";
|
||||
const char *soundsPath = "CD2.SAM";
|
||||
const char *dubbingPath = "CD.SAM";
|
||||
|
||||
DraciEngine::DraciEngine(OSystem *syst, const ADGameDescription *gameDesc)
|
||||
: Engine(syst) {
|
||||
@ -107,6 +109,9 @@ int DraciEngine::init() {
|
||||
_itemImagesArchive = new BArchive(itemImagesPath);
|
||||
_stringsArchive = new BArchive(stringsPath);
|
||||
|
||||
_soundsArchive = new SoundArchive(soundsPath);
|
||||
_dubbingArchive = new SoundArchive(dubbingPath);
|
||||
|
||||
// Load the game's fonts
|
||||
_smallFont = new Font(kFontSmall);
|
||||
_bigFont = new Font(kFontBig);
|
||||
@ -281,6 +286,9 @@ DraciEngine::~DraciEngine() {
|
||||
delete _itemImagesArchive;
|
||||
delete _stringsArchive;
|
||||
|
||||
delete _soundsArchive;
|
||||
delete _dubbingArchive;
|
||||
|
||||
// Remove all of our debug levels here
|
||||
Common::clearAllDebugChannels();
|
||||
}
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "draci/script.h"
|
||||
#include "draci/barchive.h"
|
||||
#include "draci/animation.h"
|
||||
#include "draci/sound.h"
|
||||
|
||||
namespace Draci {
|
||||
|
||||
@ -82,6 +83,9 @@ public:
|
||||
BArchive *_initArchive;
|
||||
BArchive *_stringsArchive;
|
||||
|
||||
SoundArchive *_soundsArchive;
|
||||
SoundArchive *_dubbingArchive;
|
||||
|
||||
bool _showWalkingMap;
|
||||
|
||||
Common::RandomSource _rnd;
|
||||
|
@ -7,6 +7,7 @@ MODULE_OBJS := \
|
||||
script.o \
|
||||
font.o \
|
||||
saveload.o \
|
||||
sound.o \
|
||||
sprite.o \
|
||||
screen.o \
|
||||
surface.o \
|
||||
|
160
engines/draci/sound.cpp
Normal file
160
engines/draci/sound.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/engines/draci/barchive.cpp $
|
||||
* $Id: barchive.cpp 44493 2009-09-30 16:04:21Z fingolfin $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/file.h"
|
||||
#include "common/str.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "draci/sound.h"
|
||||
#include "draci/draci.h"
|
||||
|
||||
namespace Draci {
|
||||
|
||||
void SoundArchive::openArchive(const Common::String &path) {
|
||||
// Close previously opened archive (if any)
|
||||
closeArchive();
|
||||
|
||||
debugCN(2, kDraciArchiverDebugLevel, "Loading samples %s: ", path.c_str());
|
||||
|
||||
_f = new Common::File();
|
||||
_f->open(path);
|
||||
if (_f->isOpen()) {
|
||||
debugC(2, kDraciArchiverDebugLevel, "Success");
|
||||
} else {
|
||||
debugC(2, kDraciArchiverDebugLevel, "Error");
|
||||
return;
|
||||
}
|
||||
|
||||
// Save path for reading in files later on
|
||||
_path = path;
|
||||
|
||||
// Read archive header
|
||||
debugC(2, kDraciArchiverDebugLevel, "Loading header");
|
||||
|
||||
uint totalLength = _f->readUint32LE();
|
||||
const uint kMaxSamples = 4095; // The no-sound file is exactly 16K bytes long, so don't fail on short reads
|
||||
uint sampleStarts[kMaxSamples];
|
||||
for (uint i = 0; i < kMaxSamples; ++i) {
|
||||
sampleStarts[i] = _f->readUint32LE();
|
||||
}
|
||||
|
||||
// Fill the sample table
|
||||
for (_sampleCount = 0; _sampleCount < kMaxSamples - 1; ++_sampleCount) {
|
||||
int length = sampleStarts[_sampleCount + 1] - sampleStarts[_sampleCount];
|
||||
if (length <= 0 && sampleStarts[_sampleCount] >= totalLength) // heuristics to detect the last sample
|
||||
break;
|
||||
}
|
||||
if (_sampleCount > 0) {
|
||||
debugC(2, kDraciArchiverDebugLevel, "Archive info: %d samples, %d total length",
|
||||
_sampleCount, totalLength);
|
||||
_samples = new SoundSample[_sampleCount];
|
||||
for (uint i = 0; i < _sampleCount; ++i) {
|
||||
_samples[i]._offset = sampleStarts[i];
|
||||
_samples[i]._length = sampleStarts[i+1] - sampleStarts[i];
|
||||
_samples[i]._data = NULL;
|
||||
}
|
||||
if (_samples[_sampleCount-1]._offset + _samples[_sampleCount-1]._length != totalLength &&
|
||||
_samples[_sampleCount-1]._offset + _samples[_sampleCount-1]._length - _samples[0]._offset != totalLength) {
|
||||
// WORKAROUND: the stored length is stored with the header for sounds and without the hader for dubbing. Crazy.
|
||||
debugC(2, kDraciArchiverDebugLevel, "Broken sound archive: %d != %d",
|
||||
_samples[_sampleCount-1]._offset + _samples[_sampleCount-1]._length,
|
||||
totalLength);
|
||||
closeArchive();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
debugC(2, kDraciArchiverDebugLevel, "Archive info: empty");
|
||||
}
|
||||
|
||||
// Indicate that the archive has been successfully opened
|
||||
_opened = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SoundArchive close method
|
||||
*
|
||||
* Closes the currently opened archive. It can be called explicitly to
|
||||
* free up memory.
|
||||
*/
|
||||
void SoundArchive::closeArchive() {
|
||||
clearCache();
|
||||
delete _f;
|
||||
_f = NULL;
|
||||
delete[] _samples;
|
||||
_samples = NULL;
|
||||
_sampleCount = 0;
|
||||
_path = "";
|
||||
_opened = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the cache of the open files inside the archive without closing it.
|
||||
* If the files are subsequently accessed, they are read from the disk.
|
||||
*/
|
||||
void SoundArchive::clearCache() {
|
||||
// Delete all cached data
|
||||
for (uint i = 0; i < _sampleCount; ++i) {
|
||||
_samples[i].close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief On-demand sound sample loader
|
||||
* @param i Index of file inside an archive
|
||||
* @return Pointer to a SoundSample coresponding to the opened file or NULL (on failure)
|
||||
*
|
||||
* Loads individual samples from an archive to memory on demand.
|
||||
*/
|
||||
const SoundSample *SoundArchive::getSample(uint i) {
|
||||
// Check whether requested file exists
|
||||
if (i >= _sampleCount) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
debugCN(2, kDraciArchiverDebugLevel, "Accessing sample %d from archive %s... ",
|
||||
i, _path.c_str());
|
||||
|
||||
// Check if file has already been opened and return that
|
||||
if (_samples[i]._data) {
|
||||
debugC(2, kDraciArchiverDebugLevel, "Success");
|
||||
return _samples + i;
|
||||
}
|
||||
|
||||
// Read in the file (without the file header)
|
||||
_f->seek(_samples[i]._offset);
|
||||
_samples[i]._data = new byte[_samples[i]._length];
|
||||
_f->read(_samples[i]._data, _samples[i]._length);
|
||||
|
||||
debugC(3, kDraciArchiverDebugLevel, "Cached sample %d from archive %s",
|
||||
i, _path.c_str());
|
||||
|
||||
return _samples + i;
|
||||
}
|
||||
|
||||
} // End of namespace Draci
|
||||
|
||||
|
||||
|
83
engines/draci/sound.h
Normal file
83
engines/draci/sound.h
Normal file
@ -0,0 +1,83 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/engines/draci/barchive.h $
|
||||
* $Id: barchive.h 44802 2009-10-08 21:28:57Z fingolfin $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DRACI_SOUND_H
|
||||
#define DRACI_SOUND_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "common/file.h"
|
||||
|
||||
namespace Draci {
|
||||
|
||||
/**
|
||||
* Represents individual files inside the archive.
|
||||
*/
|
||||
struct SoundSample {
|
||||
uint _offset;
|
||||
uint _length;
|
||||
byte* _data;
|
||||
|
||||
void close(void) {
|
||||
delete[] _data;
|
||||
_data = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class SoundArchive {
|
||||
public:
|
||||
SoundArchive() : _path(), _samples(NULL), _sampleCount(0), _opened(false), _f(NULL) {}
|
||||
|
||||
SoundArchive(const Common::String &path) :
|
||||
_path(), _samples(NULL), _sampleCount(0), _opened(false), _f(NULL) {
|
||||
openArchive(path);
|
||||
}
|
||||
|
||||
~SoundArchive() { closeArchive(); }
|
||||
|
||||
void closeArchive();
|
||||
void openArchive(const Common::String &path);
|
||||
uint size() const { return _sampleCount; }
|
||||
|
||||
/**
|
||||
* Checks whether there is an archive opened. Should be called before reading
|
||||
* from the archive to check whether openArchive() succeeded.
|
||||
*/
|
||||
bool isOpen() const { return _opened; }
|
||||
|
||||
void clearCache();
|
||||
|
||||
const SoundSample *getSample(uint i);
|
||||
|
||||
private:
|
||||
Common::String _path; ///< Path to file
|
||||
SoundSample *_samples; ///< Internal array of files
|
||||
uint _sampleCount; ///< Number of files in archive
|
||||
bool _opened; ///< True if the archive is opened, false otherwise
|
||||
Common::File *_f; ///< Opened file
|
||||
};
|
||||
|
||||
} // End of namespace Draci
|
||||
|
||||
#endif // DRACI_SOUND_H
|
Loading…
Reference in New Issue
Block a user