WINTERMUTE: Make BPkgFile use zlib-streams and substreams.

Note that there is still much that could be simplified here by using
substreams more extensively, instead of the specific WinterMute-solutions
that are currently in place for dcp-files.
This commit is contained in:
Einar Johan Trøan Sømåen 2012-05-09 13:48:17 +02:00 committed by Einar Johan Trøan Sømåen
parent 28c78b956d
commit 3a3304e324
6 changed files with 42 additions and 103 deletions

View File

@ -56,12 +56,13 @@ CBDiskFile::~CBDiskFile() {
HRESULT CBDiskFile::Open(Common::String Filename) {
Close();
warning("CBDiskFile::Open(%s)", Filename.c_str());
char FullPath[MAX_PATH];
for (int i = 0; i < Game->_fileManager->_singlePaths.GetSize(); i++) {
sprintf(FullPath, "%s%s", Game->_fileManager->_singlePaths[i], Filename.c_str());
CorrectSlashes(FullPath);
warning("CBDiskFile::Open - Attempting: %s", FullPath);
//_file = Common::createFileStream(FullPath);
Common::File *tempFile = new Common::File();
if(tempFile->open(FullPath)) {
@ -79,6 +80,7 @@ HRESULT CBDiskFile::Open(Common::String Filename) {
if (!_file) {
strcpy(FullPath, Filename.c_str());
CorrectSlashes(FullPath);
warning("CBDiskFile::Open - Attempting2: %s", FullPath);
//error("Tried to open %s, TODO: add SearchMan-support", Filename.c_str());
//_file = Common::createFileStream(FullPath);
Common::File *tempFile = new Common::File();

View File

@ -677,8 +677,8 @@ bool CBFileManager::IsValidPackage(const AnsiString &fileName) const {
//////////////////////////////////////////////////////////////////////////
Common::File *CBFileManager::OpenPackage(char *Name) {
//TODO
warning("Implement OpenPackage %s", Name);
//TODO: Is it really necessary to do this when we have the ScummVM-system?
warning("OpenPackage(%s)", Name);
//RestoreCurrentDir();
@ -687,12 +687,18 @@ Common::File *CBFileManager::OpenPackage(char *Name) {
for (int i = 0; i < _packagePaths.GetSize(); i++) {
sprintf(Filename, "%s%s.%s", _packagePaths[i], Name, PACKAGE_EXTENSION);
//ret = fopen(Filename, "rb");
ret->open(Filename);
if (ret->isOpen()) {
return ret;
}
}
sprintf(Filename, "%s.%s", Name, PACKAGE_EXTENSION);
ret->open(Filename);
if (ret->isOpen()) {
return ret;
}
warning("CBFileManager::OpenPackage - Couldn't load file %s", Name);
delete ret;
return NULL;
}
@ -815,22 +821,23 @@ CBFile *CBFileManager::OpenFileRaw(const char *Filename) {
return NULL;
}
}
warning("BFileManager::OpenFileRaw(%s)", Filename);
warning("Trying DiskFile");
CBDiskFile *DiskFile = new CBDiskFile(Game);
if (SUCCEEDED(DiskFile->Open(Filename))) return DiskFile;
delete DiskFile;
warning("Trying PkgFile");
CBPkgFile *PkgFile = new CBPkgFile(Game);
if (SUCCEEDED(PkgFile->Open(Filename))) return PkgFile;
delete PkgFile;
warning("Trying ResourceFile");
CBResourceFile *ResFile = new CBResourceFile(Game);
if (SUCCEEDED(ResFile->Open(Filename))) return ResFile;
delete ResFile;
warning("BFileManager::OpenFileRaw - Failed to open %s", Filename);
return NULL;
}

View File

@ -31,6 +31,7 @@
#include "BGame.h"
#include "BFileManager.h"
#include "common/file.h"
#include "common/stream.h"
namespace WinterMute {
//////////////////////////////////////////////////////////////////////
@ -74,7 +75,7 @@ HRESULT CBPackage::Close() {
//////////////////////////////////////////////////////////////////////////
HRESULT CBPackage::Read(Common::File *file, uint32 offset, byte *buffer, uint32 size) {
HRESULT CBPackage::Read(Common::SeekableReadStream *file, uint32 offset, byte *buffer, uint32 size) {
HRESULT ret;
if (FAILED(ret = Open())) return ret;
else {
@ -85,7 +86,7 @@ HRESULT CBPackage::Read(Common::File *file, uint32 offset, byte *buffer, uint32
}
//////////////////////////////////////////////////////////////////////////
Common::File *CBPackage::GetFilePointer() {
Common::SeekableReadStream *CBPackage::GetFilePointer() {
Common::File *file = Game->_fileManager->OpenPackage(_name);
if (!file) {
Game->_fileManager->RequestCD(_cD, _name, "");
@ -95,7 +96,7 @@ Common::File *CBPackage::GetFilePointer() {
}
//////////////////////////////////////////////////////////////////////////
void CBPackage::CloseFilePointer(Common::File*& file) {
void CBPackage::CloseFilePointer(Common::SeekableReadStream*& file) {
delete file;
file = NULL;
}

View File

@ -33,24 +33,24 @@
#include "BBase.h"
namespace Common {
class File;
class SeekableReadStream;
}
namespace WinterMute {
class CBPackage : public CBBase {
public:
Common::File *GetFilePointer();
void CloseFilePointer(Common::File*& file);
Common::SeekableReadStream *GetFilePointer();
void CloseFilePointer(Common::SeekableReadStream*& file);
bool _boundToExe;
byte _priority;
HRESULT Read(Common::File *file, uint32 offset, byte *buffer, uint32 size);
HRESULT Read(Common::SeekableReadStream *file, uint32 offset, byte *buffer, uint32 size);
HRESULT Close();
HRESULT Open();
char *_name;
int _cD;
Common::File *_file;
Common::SeekableReadStream *_file;
CBPackage(CBGame *inGame);
virtual ~CBPackage();

View File

@ -32,17 +32,10 @@
#include "BGame.h"
#include "BFileManager.h"
#include "common/util.h"
#if _DEBUG
#pragma comment(lib, "zlib_d.lib")
#else
#pragma comment(lib, "zlib.lib")
#endif
extern "C" {
#include "zlib.h"
}
#include "common/file.h"
#include "common/stream.h"
#include "common/substream.h"
#include "common/zlib.h"
namespace WinterMute {
@ -52,14 +45,8 @@ CBPkgFile::CBPkgFile(CBGame *inGame): CBFile(inGame) {
_file = NULL;
_compressed = false;
_stream.zalloc = (alloc_func)0;
_stream.zfree = (free_func)0;
_stream.opaque = (voidpf)0;
_inflateInit = false;
}
//////////////////////////////////////////////////////////////////////////
CBPkgFile::~CBPkgFile() {
Close();
@ -84,10 +71,16 @@ HRESULT CBPkgFile::Open(Common::String Filename) {
_file = _fileEntry->_package->GetFilePointer();
if (!_file) return E_FAIL;
// TODO: Cleanup
_compressed = (_fileEntry->_compressedLength != 0);
_size = _fileEntry->_length;
if (_compressed) {
// TODO: Really, most of this logic might be doable directly in the fileEntry?
// But for now, this should get us rolling atleast.
_file = wrapCompressedReadStream(new Common::SeekableSubReadStream(_file, _fileEntry->_offset, _fileEntry->_offset + _fileEntry->_length, DisposeAfterUse::YES));
}
SeekToPos(0);
return S_OK;
@ -102,12 +95,10 @@ HRESULT CBPkgFile::Close() {
}
_file = NULL;
// TODO: Do we really need to take care of our position and size at all (or could (Safe)SubStreams fix that for us?
_pos = 0;
_size = 0;
if (_inflateInit) inflateEnd(&_stream);
_inflateInit = false;
return S_OK;
}
@ -123,32 +114,7 @@ HRESULT CBPkgFile::Read(void *Buffer, uint32 Size) {
if (Size == 0) return E_FAIL;
}
if (_compressed) {
uint32 InitOut = _stream.total_out;
_stream.avail_out = Size;
_stream.next_out = (byte *)Buffer;
while (_stream.total_out - InitOut < Size && _stream.total_in < _fileEntry->_compressedLength) {
// needs to read more data?
if (_stream.avail_in == 0) {
_stream.avail_in = MIN((long unsigned int)COMPRESSED_BUFFER_SIZE, _fileEntry->_compressedLength - _stream.total_in); // TODO: long unsigned int????
_fileEntry->_package->Read(_file, _fileEntry->_offset + _stream.total_in, _compBuffer, _stream.avail_in);
_stream.next_in = _compBuffer;
}
int res = inflate(&_stream, Z_SYNC_FLUSH);
if (res != Z_OK && res != Z_STREAM_END) {
Game->LOG(0, "zlib error: %d", res);
ret = E_FAIL;
break;
}
}
} else {
ret = _fileEntry->_package->Read(_file, _fileEntry->_offset + _pos, (byte *)Buffer, Size);
}
ret = _file->read(Buffer, Size);
_pos += Size;
@ -186,42 +152,6 @@ HRESULT CBPkgFile::SeekToPos(uint32 NewPos) {
HRESULT ret = S_OK;
// seek compressed stream to NewPos
if (_compressed) {
byte StreamBuffer[STREAM_BUFFER_SIZE];
if (_inflateInit) inflateEnd(&_stream);
_inflateInit = false;
_stream.avail_in = 0;
_stream.next_in = _compBuffer;
_stream.avail_out = MIN((uint32)STREAM_BUFFER_SIZE, NewPos); //TODO: remove cast.
_stream.next_out = StreamBuffer;
inflateInit(&_stream);
_inflateInit = true;
while (_stream.total_out < NewPos && _stream.total_in < _fileEntry->_compressedLength) {
// needs to read more data?
if (_stream.avail_in == 0) {
_stream.avail_in = MIN((long unsigned int)COMPRESSED_BUFFER_SIZE, _fileEntry->_compressedLength - _stream.total_in); // TODO: long unsigned int???
_fileEntry->_package->Read(_file, _fileEntry->_offset + _stream.total_in, _compBuffer, _stream.avail_in);
_stream.next_in = _compBuffer;
}
// needs more space?
if (_stream.avail_out == 0) {
_stream.next_out = StreamBuffer;
_stream.avail_out = MIN((long unsigned int)STREAM_BUFFER_SIZE, NewPos - _stream.total_out); // TODO: long unsigned int???.
}
// stream on!
int res = inflate(&_stream, Z_SYNC_FLUSH);
if (res != Z_OK && res != Z_STREAM_END) {
ret = E_FAIL;
break;
}
}
}
_pos = NewPos;
return ret;
}

View File

@ -37,6 +37,7 @@
#define COMPRESSED_BUFFER_SIZE 4096
namespace Common {
class SeekableReadStream;
class File;
}
@ -55,9 +56,7 @@ private:
HRESULT SeekToPos(uint32 NewPos);
bool _compressed;
CBFileEntry *_fileEntry;
z_stream _stream;
byte _compBuffer[COMPRESSED_BUFFER_SIZE];
Common::File *_file;
Common::SeekableReadStream *_file;
};
} // end of namespace WinterMute