mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-21 17:29:39 +00:00
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:
parent
28c78b956d
commit
3a3304e324
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user