From 3a3304e324970032638b7a9eca9c264e26dc34c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20Johan=20Tr=C3=B8an=20S=C3=B8m=C3=A5en?= Date: Wed, 9 May 2012 13:48:17 +0200 Subject: [PATCH] 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. --- engines/wintermute/BDiskFile.cpp | 4 +- engines/wintermute/BFileManager.cpp | 21 ++++--- engines/wintermute/BPackage.cpp | 7 ++- engines/wintermute/BPackage.h | 10 +-- engines/wintermute/BPkgFile.cpp | 98 +++++------------------------ engines/wintermute/BPkgFile.h | 5 +- 6 files changed, 42 insertions(+), 103 deletions(-) diff --git a/engines/wintermute/BDiskFile.cpp b/engines/wintermute/BDiskFile.cpp index 24c25f3bedd..6e66bb721ea 100644 --- a/engines/wintermute/BDiskFile.cpp +++ b/engines/wintermute/BDiskFile.cpp @@ -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(); diff --git a/engines/wintermute/BFileManager.cpp b/engines/wintermute/BFileManager.cpp index fa491b62df7..0967df5518b 100644 --- a/engines/wintermute/BFileManager.cpp +++ b/engines/wintermute/BFileManager.cpp @@ -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; } diff --git a/engines/wintermute/BPackage.cpp b/engines/wintermute/BPackage.cpp index 64e19491d51..56774c64bd2 100644 --- a/engines/wintermute/BPackage.cpp +++ b/engines/wintermute/BPackage.cpp @@ -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; } diff --git a/engines/wintermute/BPackage.h b/engines/wintermute/BPackage.h index 347582da4ce..586088174f7 100644 --- a/engines/wintermute/BPackage.h +++ b/engines/wintermute/BPackage.h @@ -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(); diff --git a/engines/wintermute/BPkgFile.cpp b/engines/wintermute/BPkgFile.cpp index b8bd760ced0..441a990ecb0 100644 --- a/engines/wintermute/BPkgFile.cpp +++ b/engines/wintermute/BPkgFile.cpp @@ -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; } diff --git a/engines/wintermute/BPkgFile.h b/engines/wintermute/BPkgFile.h index 3d165c4097f..9b70d37ed66 100644 --- a/engines/wintermute/BPkgFile.h +++ b/engines/wintermute/BPkgFile.h @@ -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