diff options
author | Paul Gilbert | 2016-02-21 21:35:55 -0500 |
---|---|---|
committer | Paul Gilbert | 2016-02-21 21:35:55 -0500 |
commit | f8c6724112d9b6161a0df8ee31d98d13b36d2b40 (patch) | |
tree | 6a8130257234330848e8ea30885fbab51f54906d | |
parent | ed5ae8412dee5cadef806ad83a049ac1bc85ec4d (diff) | |
download | scummvm-rg350-f8c6724112d9b6161a0df8ee31d98d13b36d2b40.tar.gz scummvm-rg350-f8c6724112d9b6161a0df8ee31d98d13b36d2b40.tar.bz2 scummvm-rg350-f8c6724112d9b6161a0df8ee31d98d13b36d2b40.zip |
TITANIC: Fleshed out CompressedFile class
-rw-r--r-- | engines/titanic/compressed_file.cpp | 168 | ||||
-rw-r--r-- | engines/titanic/compressed_file.h | 65 | ||||
-rw-r--r-- | engines/titanic/compression.cpp | 142 | ||||
-rw-r--r-- | engines/titanic/compression.h | 106 | ||||
-rw-r--r-- | engines/titanic/main_game_window.cpp | 3 | ||||
-rw-r--r-- | engines/titanic/module.mk | 1 | ||||
-rw-r--r-- | engines/titanic/screen_manager.cpp | 2 | ||||
-rw-r--r-- | engines/titanic/screen_manager.h | 4 |
8 files changed, 349 insertions, 142 deletions
diff --git a/engines/titanic/compressed_file.cpp b/engines/titanic/compressed_file.cpp index ea760167d7..c200370eae 100644 --- a/engines/titanic/compressed_file.cpp +++ b/engines/titanic/compressed_file.cpp @@ -24,82 +24,16 @@ namespace Titanic { -DecompressorData::DecompressorData() { - _field0 = 0; - _field4 = 0; - _field8 = 0; - _fieldC = 0; - _field10 = 0; - _field14 = 0; -} - -/*------------------------------------------------------------------------*/ - -Decompressor::Decompressor() { - _createFn = nullptr; - _destroyFn = nullptr; - _field18 = 0; - _dataPtr = nullptr; - _field28 = 0; -} - -void Decompressor::load(const char *version, int v) { - if (!version || *version != '1') - error("Bad version"); - - _field18 = 0; - if (!_createFn) { - _createFn = &Decompressor::createMethod; - _field28 = 0; - } - - if (!_destroyFn) { - _destroyFn = &Decompressor::destroyMethod; - } - - _dataPtr = (this->*_createFn)(_field28, 1, 24); - _dataPtr->_field14 = 0; - _dataPtr->_fieldC = 0; - if (v < 0) { - v = -v; - _dataPtr->_fieldC = 1; - } - - if (v < 8 || v > 15) - error("Bad parameter"); - - _dataPtr->_field10 = v; - _dataPtr->_field14 = sub1(_dataPtr->_fieldC ? nullptr : &Decompressor::method3, 1 << v); - - if (_dataPtr->_field14) - sub2(); - else - close(); -} - -int Decompressor::sub1(Method3Fn fn, int v) { - return 0; -} - -void Decompressor::close() { - -} - -DecompressorData *Decompressor::createMethod(int v1, int v2, int v3) { - return new DecompressorData(); -} - -void Decompressor::destroyMethod(DecompressorData *ptr) { - delete ptr; -} - -/*------------------------------------------------------------------------*/ +#define BUFFER_SIZE 1024 CompressedFile::CompressedFile() : SimpleFile() { - _fileMode = 0; - _isReading = 0; - _field260 = 0; - _mode = 0; + _fileMode = COMPMODE_NONE; + Common::fill(&_writeBuffer[0], &_writeBuffer[516], 0); + _dataStartPtr = nullptr; + _dataPtr = nullptr; + _dataRemaining = 0; + _dataMaxSize = 0; + _dataCount = 0; } CompressedFile::~CompressedFile() { @@ -108,27 +42,58 @@ CompressedFile::~CompressedFile() { void CompressedFile::open(const Common::String &name) { SimpleFile::open(name); - _decompressor.load(); - _fileMode = 2; + _compression.initDecompress(); + _fileMode = COMPMODE_READ; + _dataPtr = _dataStartPtr = new byte[BUFFER_SIZE]; + _dataMaxSize = BUFFER_SIZE; + _dataRemaining = 0; + _dataCount = 0; } void CompressedFile::open(Common::SeekableReadStream *stream) { SimpleFile::open(stream); - _decompressor.load(); - _fileMode = 2; + _compression.initDecompress(); + _fileMode = COMPMODE_READ; + _dataPtr = _dataStartPtr = new byte[BUFFER_SIZE]; + _dataMaxSize = BUFFER_SIZE; + _dataRemaining = 0; + _dataCount = 0; } void CompressedFile::open(Common::OutSaveFile *stream) { SimpleFile::open(stream); - _decompressor.load(); - _fileMode = 1; + _compression.initCompress(); + _fileMode = COMPMODE_WRITE; } void CompressedFile::close() { - _queue.clear(); - SimpleFile::close(); + int result; + + switch (_fileMode) { + case COMPMODE_WRITE: + do { + _compression._destPtr = _writeBuffer; + _compression._destCount = 512; + result = _compression.compress(4); + int count = 512 - _compression._destCount; + + if (count) + write(_writeBuffer, count); + } while (!result); + break; + case COMPMODE_READ: + _compression.close(); + delete[] _dataStartPtr; + _dataStartPtr = _dataPtr = nullptr; + _dataRemaining = _dataMaxSize = 0; + + SimpleFile::close(); + break; + default: + break; + } } size_t CompressedFile::unsafeRead(void *dst, size_t count) { @@ -144,22 +109,51 @@ size_t CompressedFile::unsafeRead(void *dst, size_t count) { byte *dataPtr = (byte *)dst; while (count > 0) { - if (_queue.empty()) { + if (!_dataRemaining) { decompress(); - if (_queue.empty()) + if (!_dataRemaining) break; } - *dataPtr++ = _queue.pop(); - ++bytesRead; - --count; + *dataPtr++ = *_dataPtr++; + --_dataRemaining; } return bytesRead; } void CompressedFile::decompress() { + const size_t COUNT = 1; + byte fileByte; + int count; + + _dataPtr = _dataStartPtr; + _compression._destPtr = _dataStartPtr; + _compression._destCount = _dataMaxSize; + + if (_dataMaxSize < 0x100) + return; + + // Loop to get data from the file as needed and decompress + do { + if (!_compression._srcCount) { + // Read in next byte from the source file + if (!SimpleFile::unsafeRead(&fileByte, 1)) + break; + // Set up the decompressor to process the data + _compression._srcCount = COUNT; + _compression._srcPtr = &fileByte; + } + + int count = _compression.decompress(COUNT); + _dataRemaining = _dataMaxSize - _compression._destCount; + + if (count == COUNT) { + _dataCount = COUNT; + break; + } + } while (!count && _compression._destCount > 0x100); } } // End of namespace Titanic diff --git a/engines/titanic/compressed_file.h b/engines/titanic/compressed_file.h index cd9cf8377d..30b925d9b6 100644 --- a/engines/titanic/compressed_file.h +++ b/engines/titanic/compressed_file.h @@ -25,66 +25,27 @@ #include "common/scummsys.h" #include "common/file.h" -#include "common/queue.h" +#include "titanic/compression.h" #include "titanic/simple_file.h" #include "titanic/string.h" namespace Titanic { -class Decompressor; -class DecompressorData; - -typedef DecompressorData *(Decompressor::*DecompressorCreateFn)(int v1, int v2, int v3); -typedef void(Decompressor::*DecompressorDestroyFn)(DecompressorData *ptr); -typedef void(Decompressor::*Method3Fn)(); - -class DecompressorData { -public: - int _field0; - int _field4; - int _field8; - int _fieldC; - int _field10; - int _field14; -public: - DecompressorData(); -}; - -class Decompressor { -private: - DecompressorCreateFn _createFn; - DecompressorDestroyFn _destroyFn; - int _field18; - DecompressorData *_dataPtr; - int _field28; - - DecompressorData *createMethod(int v1, int v2, int v3); - - void destroyMethod(DecompressorData *ptr); - - void method3() { - // TODO - } - - int sub1(Method3Fn fn, int v); - - void sub2() {} -public: - Decompressor(); - - void load(const char *version = "1.0.4", int v = 15); - - void close(); -}; +enum CompressedFileMode { COMPMODE_NONE, COMPMODE_WRITE, COMPMODE_READ }; +/** + * Derived file that handles compressed files + */ class CompressedFile : public SimpleFile { private: - Decompressor _decompressor; - Common::Queue<byte> _queue; - int _fileMode; - int _isReading; - int _field260; - int _mode; + Compression _compression; + CompressedFileMode _fileMode; + byte _writeBuffer[516]; + byte *_dataStartPtr; + byte *_dataPtr; + int _dataRemaining; + int _dataMaxSize; + int _dataCount; /** * Decompress data from the source file diff --git a/engines/titanic/compression.cpp b/engines/titanic/compression.cpp new file mode 100644 index 0000000000..9dad905370 --- /dev/null +++ b/engines/titanic/compression.cpp @@ -0,0 +1,142 @@ +/* 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. + * + */ + +#include "titanic/compression.h" +#include "common/textconsole.h" + +namespace Titanic { + +CompressionData::CompressionData() { + _commandNum = 0; + _field4 = 0; + _field8 = 0; + _fieldC = 0; + _field10 = 0; + _field14 = 0; +} + +/*------------------------------------------------------------------------*/ + +Compression::Compression() { + _srcPtr = nullptr; + _srcCount = 0; + _field8 = 0; + _destPtr = nullptr; + _destCount = 0; + _field14 = 0; + _field18 = 0; + _compressionData = nullptr; + _createFn = nullptr; + _destroyFn = nullptr; + _field28 = 0; + _field2C = 0; + _field30 = 0; + _field34 = 0; +} + +Compression::~Compression() { + close(); +} + +void Compression::initDecompress(const char *version, int v) { + if (!version || *version != '1') + error("Bad version"); + + _field18 = 0; + if (!_createFn) { + _createFn = &Compression::createMethod; + _field28 = 0; + } + + if (!_destroyFn) { + _destroyFn = &Compression::destroyMethod; + } + + _compressionData = (this->*_createFn)(_field28, 1); + _compressionData->_field14 = 0; + _compressionData->_fieldC = 0; + if (v < 0) { + v = -v; + _compressionData->_fieldC = 1; + } + + if (v < 8 || v > 15) + error("Bad parameter"); + + _compressionData->_field10 = v; + _compressionData->_field14 = sub1(_compressionData->_fieldC ? nullptr : &Compression::method3, 1 << v); + + if (_compressionData->_field14) + sub2(); + else + close(); +} + +void Compression::initCompress(const char *version, int v) { + error("TODO"); +} + + +int Compression::sub1(Method3Fn fn, int v) { + return 0; +} + +void Compression::close() { + if (_destroyFn) + (this->*_destroyFn)(_compressionData); +} + +CompressionData *Compression::createMethod(int v1, int v2) { + return new CompressionData(); +} + +void Compression::destroyMethod(CompressionData *ptr) { + delete ptr; +} + +int Compression::compress(int v) { + return 0; +} + +int Compression::decompress(size_t count) { +/* + if (!_compressionData || !_srcPtr || !count) + // Needed fields aren't set + return -2; + + int result = -5; + do { + int ebx = 5; + + switch (_compressionData->_commandNum) { + case 0: + if (_compressionData->_field4) + return result; + + default: + return -2; + } + }*/ + return -2; +} + +} // End of namespace Titanic diff --git a/engines/titanic/compression.h b/engines/titanic/compression.h new file mode 100644 index 0000000000..6d3a5b9ac2 --- /dev/null +++ b/engines/titanic/compression.h @@ -0,0 +1,106 @@ +/* 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. + * + */ + +#ifndef TITANIC_COMPRESSION_H +#define TITANIC_COMPRESSION_H + +#include "common/scummsys.h" + +namespace Titanic { + +class Compression; +class CompressionData; + +typedef CompressionData *(Compression::*CompressionCreateFn)(int v1, int v2); +typedef void(Compression::*CompressionDestroyFn)(CompressionData *ptr); +typedef void(Compression::*Method3Fn)(); + +class CompressionData { +public: + int _commandNum; + int _field4; + int _field8; + int _fieldC; + int _field10; + int _field14; +public: + CompressionData(); +}; + +class Compression { +private: + CompressionData *createMethod(int v1, int v2); + + void destroyMethod(CompressionData *ptr); + + void method3() { + // TODO + } + + int sub1(Method3Fn fn, int v); + + void sub2() {} +public: + byte *_srcPtr; + int _srcCount; + int _field8; + byte *_destPtr; + int _destCount; + int _field14; + int _field18; + CompressionData *_compressionData; + CompressionCreateFn _createFn; + CompressionDestroyFn _destroyFn; + int _field28; + int _field2C; + int _field30; + int _field34; +public: + Compression(); + ~Compression(); + + /** + * Initialize for decompression + */ + void initDecompress(const char *version = "1.0.4", int v = 15); + + /** + * Initialize for compression + */ + void initCompress(const char *version = "1.0.4", int v = -1); + + void close(); + + /** + * Compress data + */ + int compress(int v); + + /** + * Decompress data + */ + int decompress(size_t count); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_COMPRESSION_H */ diff --git a/engines/titanic/main_game_window.cpp b/engines/titanic/main_game_window.cpp index 9087cafb80..78e07e9af2 100644 --- a/engines/titanic/main_game_window.cpp +++ b/engines/titanic/main_game_window.cpp @@ -39,6 +39,9 @@ bool CMainGameWindow::Create() { bool result = image.loadResource("TITANIC"); if (!result) return true; + + // TODO: Stuff + return true; } } // End of namespace Titanic diff --git a/engines/titanic/module.mk b/engines/titanic/module.mk index abd351250d..7d126b4094 100644 --- a/engines/titanic/module.mk +++ b/engines/titanic/module.mk @@ -2,6 +2,7 @@ MODULE := engines/titanic MODULE_OBJS := \ compressed_file.o \ + compression.o \ detection.o \ direct_draw.o \ font.o \ diff --git a/engines/titanic/screen_manager.cpp b/engines/titanic/screen_manager.cpp index 61b6ff4762..08262dfd61 100644 --- a/engines/titanic/screen_manager.cpp +++ b/engines/titanic/screen_manager.cpp @@ -70,7 +70,7 @@ OSScreenManager::~OSScreenManager() { destroyFrontAndBackBuffers(); } -void OSScreenManager::setMode(int width, int height, int bpp, int numBackSurfaces, bool flag2) { +void OSScreenManager::setMode(int width, int height, int bpp, uint numBackSurfaces, bool flag2) { destroyFrontAndBackBuffers(); _directDrawManager.initVideo(width, height, bpp, numBackSurfaces); diff --git a/engines/titanic/screen_manager.h b/engines/titanic/screen_manager.h index 4647c71c81..4836bb33fc 100644 --- a/engines/titanic/screen_manager.h +++ b/engines/titanic/screen_manager.h @@ -67,7 +67,7 @@ public: virtual void setWindowHandle(int v); virtual bool resetWindowHandle(int v); - virtual void setMode(int width, int height, int bpp, int numBackSurfaces, bool flag2) = 0; + virtual void setMode(int width, int height, int bpp, uint numBackSurfaces, bool flag2) = 0; virtual void proc5() = 0; virtual void proc6() = 0; virtual void proc7() = 0; @@ -116,7 +116,7 @@ public: OSScreenManager(TitanicEngine *vm); virtual ~OSScreenManager(); - virtual void setMode(int width, int height, int bpp, int numBackSurfaces, bool flag2); + virtual void setMode(int width, int height, int bpp, uint numBackSurfaces, bool flag2); virtual void proc5(); virtual void proc6(); virtual void proc7(); |